From 340583fa35f5471ac51a930df7140845ff938533 Mon Sep 17 00:00:00 2001 From: Tingqian Li Date: Thu, 8 Jul 2021 12:18:09 +0800 Subject: [PATCH 01/13] Tq/revise asinh (#6498) * update spec Signed-off-by: Li, Tingqian * use RTTI macro Signed-off-by: Li, Tingqian * fix op scope typo Signed-off-by: Li, Tingqian * simplify evaluate template function Signed-off-by: Li, Tingqian * override validate_and_infer_types() to align with spec Signed-off-by: Li, Tingqian * Add visitor API test Signed-off-by: Li, Tingqian * Add type_prop test Signed-off-by: Li, Tingqian * Add SLT asinh test in cpu/gpu plugin Signed-off-by: Li, Tingqian * change `T` in the spec to *T* Signed-off-by: Li, Tingqian * refector spec according to Cos Signed-off-by: Li, Tingqian * Support element type of integral Signed-off-by: Li, Tingqian * Add new cpp files into CMakeLists.txt Signed-off-by: Li, Tingqian --- docs/ops/arithmetic/Asinh_3.md | 36 +++++++++---------- .../serialization/single_layer/activation.cpp | 1 + .../single_layer_tests/activation.cpp | 2 ++ .../single_layer_tests/activation.cpp | 1 + .../single_layer/activation.hpp | 1 + .../layer_tests_summary/utils/constants.py | 1 + .../ngraph_functions/utils/ngraph_helpers.hpp | 1 + .../ngraph_functions/src/activation.cpp | 2 ++ ngraph/core/include/ngraph/op/asinh.hpp | 4 +-- .../ngraph/runtime/reference/asinh.hpp | 13 ++++++- ngraph/core/src/op/asinh.cpp | 24 +++++++------ ngraph/test/CMakeLists.txt | 2 ++ ngraph/test/backend/asinh.in.cpp | 15 ++++++++ ngraph/test/type_prop/asinh.cpp | 9 +++++ ngraph/test/visitors/op/asinh.cpp | 11 ++++++ 15 files changed, 89 insertions(+), 34 deletions(-) create mode 100644 ngraph/test/type_prop/asinh.cpp create mode 100644 ngraph/test/visitors/op/asinh.cpp diff --git a/docs/ops/arithmetic/Asinh_3.md b/docs/ops/arithmetic/Asinh_3.md index 9db15defa47..6fae01555d0 100644 --- a/docs/ops/arithmetic/Asinh_3.md +++ b/docs/ops/arithmetic/Asinh_3.md @@ -4,33 +4,29 @@ **Category**: Arithmetic unary operation -**Short description**: *Asinh* performs element-wise hyperbolic inverse sine (arcsinh) operation with given tensor. +**Short description**: *Asinh* performs element-wise inverse hyperbolic sine operation (arcsinh) on a given input tensor. -**Attributes**: - - No attributes available. - -**Inputs** - -* **1**: A tensor of type *T*. **Required.** - -**Outputs** - -* **1**: The result of element-wise asinh operation. A tensor of type *T*. - -**Types** - -* *T*: any floating point type. - -*Asinh* does the following with the input tensor *a*: +**Detailed description**: *Asinh* performs element-wise inverse hyperbolic sine operation on a given input tensor, based on the following mathematical formula: \f[ a_{i} = asinh(a_{i}) \f] -**Examples** +**Attributes**: *Asinh* operation has no attributes. -*Example 1* +**Inputs** + +* **1**: A tensor of type *T* and arbitrary shape. **Required.** + +**Outputs** + +* **1**: The result of element-wise *Asinh* operation. A tensor of type *T* and the same shape as input tensor. + +**Types** + +* *T*: any numeric type. + +**Example** ```xml diff --git a/inference-engine/tests/functional/inference_engine/serialization/single_layer/activation.cpp b/inference-engine/tests/functional/inference_engine/serialization/single_layer/activation.cpp index 371808cbbc5..355afbaf687 100644 --- a/inference-engine/tests/functional/inference_engine/serialization/single_layer/activation.cpp +++ b/inference-engine/tests/functional/inference_engine/serialization/single_layer/activation.cpp @@ -37,6 +37,7 @@ const std::map>> activationTypes {Negative, {}}, {Acos, {}}, {Asin, {}}, + {Asinh, {}}, {Atan, {}}, {Cos, {}}, {Cosh, {}}, diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/activation.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/activation.cpp index 0c6a8763844..a1a62dcd2dc 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/activation.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/activation.cpp @@ -38,6 +38,7 @@ const std::map>> activationTypes {Negative, {}}, {Acos, {}}, {Asin, {}}, + {Asinh, {}}, {Atan, {}}, {Cos, {}}, {Cosh, {}}, @@ -65,6 +66,7 @@ const std::map>> activationTypes // List of operations that should be tested also with integer precision const std::map>> intActivationTypes = { + {Asinh, {}}, {Atan, {}}, {Negative, {}}, {Ceiling, {}}, diff --git a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/single_layer_tests/activation.cpp b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/single_layer_tests/activation.cpp index c62641c0b4c..6bbf98451fe 100644 --- a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/single_layer_tests/activation.cpp +++ b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/single_layer_tests/activation.cpp @@ -35,6 +35,7 @@ const std::map>> activationTypes {Negative, {}}, {Acos, {}}, {Asin, {}}, + {Asinh, {}}, {Atan, {}}, {Cos, {}}, {Cosh, {}}, diff --git a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/single_layer/activation.hpp b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/single_layer/activation.hpp index 684942ee184..5a9c5226f6f 100644 --- a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/single_layer/activation.hpp +++ b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/single_layer/activation.hpp @@ -40,6 +40,7 @@ static std::map activationNames = {ngraph::helpers::ActivationTypes::Negative, "Negative"}, {ngraph::helpers::ActivationTypes::Acos, "Acos"}, {ngraph::helpers::ActivationTypes::Asin, "Asin"}, + {ngraph::helpers::ActivationTypes::Asinh, "Asinh"}, {ngraph::helpers::ActivationTypes::Atan, "Atan"}, {ngraph::helpers::ActivationTypes::Cos, "Cos"}, {ngraph::helpers::ActivationTypes::Cosh, "Cosh"}, diff --git a/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py b/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py index 4c3cf62280b..cf562e5ead7 100644 --- a/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py +++ b/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py @@ -6,6 +6,7 @@ VERIFIED_OP_REFERENCES = [ 'Acos-1', 'Add-1', 'Asin-1', + 'Asinh-3', 'Assign-6', 'AvgPool-1', 'BatchNormInference-5', diff --git a/inference-engine/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/utils/ngraph_helpers.hpp b/inference-engine/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/utils/ngraph_helpers.hpp index de2dbab0612..47405a8e51c 100644 --- a/inference-engine/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/utils/ngraph_helpers.hpp +++ b/inference-engine/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/utils/ngraph_helpers.hpp @@ -100,6 +100,7 @@ enum ActivationTypes { Negative, Acos, Asin, + Asinh, Atan, Cos, Cosh, diff --git a/inference-engine/tests/ngraph_helpers/ngraph_functions/src/activation.cpp b/inference-engine/tests/ngraph_helpers/ngraph_functions/src/activation.cpp index 97dea94963a..d8dce877b0f 100644 --- a/inference-engine/tests/ngraph_helpers/ngraph_functions/src/activation.cpp +++ b/inference-engine/tests/ngraph_helpers/ngraph_functions/src/activation.cpp @@ -48,6 +48,8 @@ std::shared_ptr makeActivation(const ngraph::Output &in, return std::make_shared(in); case ngraph::helpers::ActivationTypes::Asin: return std::make_shared(in); + case ngraph::helpers::ActivationTypes::Asinh: + return std::make_shared(in); case ngraph::helpers::ActivationTypes::Atan: return std::make_shared(in); case ngraph::helpers::ActivationTypes::Cos: diff --git a/ngraph/core/include/ngraph/op/asinh.hpp b/ngraph/core/include/ngraph/op/asinh.hpp index 1f781862b9d..62a4eba36a4 100644 --- a/ngraph/core/include/ngraph/op/asinh.hpp +++ b/ngraph/core/include/ngraph/op/asinh.hpp @@ -19,8 +19,8 @@ namespace ngraph class NGRAPH_API Asinh : public util::UnaryElementwiseArithmetic { public: - static constexpr NodeTypeInfo type_info{"Asinh", 3}; - const NodeTypeInfo& get_type_info() const override { return type_info; } + NGRAPH_RTTI_DECLARATION; + /// \brief Constructs an Asinh operation. Asinh() = default; /// \brief Constructs an Asinh operation. diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/asinh.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/asinh.hpp index 02db44c13b4..9fc58a3dff4 100644 --- a/ngraph/core/reference/include/ngraph/runtime/reference/asinh.hpp +++ b/ngraph/core/reference/include/ngraph/runtime/reference/asinh.hpp @@ -13,7 +13,8 @@ namespace ngraph { namespace reference { - template + template ::value, bool>::type = true> void asinh(const T* arg, T* out, size_t count) { for (size_t i = 0; i < count; i++) @@ -21,6 +22,16 @@ namespace ngraph out[i] = std::asinh(arg[i]); } } + + template ::value, bool>::type = true> + void asinh(const T* arg, T* out, size_t count) + { + for (size_t i = 0; i < count; i++) + { + out[i] = std::roundl(std::asinh(arg[i])); + } + } } // namespace reference } // namespace runtime } // namespace ngraph diff --git a/ngraph/core/src/op/asinh.cpp b/ngraph/core/src/op/asinh.cpp index ed7b2191bd6..16ea8b046d1 100644 --- a/ngraph/core/src/op/asinh.cpp +++ b/ngraph/core/src/op/asinh.cpp @@ -7,6 +7,7 @@ #include "itt.hpp" #include "ngraph/op/asinh.hpp" +#include "ngraph/op/util/elementwise_args.hpp" #include "ngraph/runtime/host_tensor.hpp" #include "ngraph/runtime/reference/asinh.hpp" #include "ngraph/type/element_type.hpp" @@ -14,7 +15,7 @@ using namespace std; using namespace ngraph; -constexpr NodeTypeInfo op::v3::Asinh::type_info; +NGRAPH_RTTI_DEFINITION(op::v3::Asinh, "Asinh", 3, util::UnaryElementwiseArithmetic); op::v3::Asinh::Asinh(const Output& arg) : UnaryElementwiseArithmetic(arg) @@ -32,25 +33,26 @@ shared_ptr op::v3::Asinh::clone_with_new_inputs(const OutputVector& new_ar namespace asinhop { template - bool evaluate(const HostTensorPtr& arg0, const HostTensorPtr& out) + inline bool evaluate(const HostTensorPtr& arg0, const HostTensorPtr& out, const size_t count) { - runtime::reference::asinh( - arg0->get_data_ptr(), out->get_data_ptr(), shape_size(arg0->get_shape())); + runtime::reference::asinh(arg0->get_data_ptr(), out->get_data_ptr(), count); return true; } bool evaluate_asinh(const HostTensorPtr& arg0, const HostTensorPtr& out) { bool rc = true; + size_t count = shape_size(arg0->get_shape()); out->set_unary(arg0); + switch (arg0->get_element_type()) { - NGRAPH_TYPE_CASE(evaluate_asinh, i32, arg0, out); - NGRAPH_TYPE_CASE(evaluate_asinh, i64, arg0, out); - NGRAPH_TYPE_CASE(evaluate_asinh, u32, arg0, out); - NGRAPH_TYPE_CASE(evaluate_asinh, u64, arg0, out); - NGRAPH_TYPE_CASE(evaluate_asinh, f16, arg0, out); - NGRAPH_TYPE_CASE(evaluate_asinh, f32, arg0, out); + NGRAPH_TYPE_CASE(evaluate_asinh, i32, arg0, out, count); + NGRAPH_TYPE_CASE(evaluate_asinh, i64, arg0, out, count); + NGRAPH_TYPE_CASE(evaluate_asinh, u32, arg0, out, count); + NGRAPH_TYPE_CASE(evaluate_asinh, u64, arg0, out, count); + NGRAPH_TYPE_CASE(evaluate_asinh, f16, arg0, out, count); + NGRAPH_TYPE_CASE(evaluate_asinh, f32, arg0, out, count); default: rc = false; break; } return rc; @@ -65,7 +67,7 @@ bool op::v3::Asinh::evaluate(const HostTensorVector& outputs, const HostTensorVe bool op::v3::Asinh::has_evaluate() const { - NGRAPH_OP_SCOPE(v1_Asinh_has_evaluate); + NGRAPH_OP_SCOPE(v3_Asinh_has_evaluate); switch (get_input_element_type(0)) { case ngraph::element::i32: diff --git a/ngraph/test/CMakeLists.txt b/ngraph/test/CMakeLists.txt index 8147e9008bd..d016bbd245c 100644 --- a/ngraph/test/CMakeLists.txt +++ b/ngraph/test/CMakeLists.txt @@ -95,6 +95,7 @@ set(SRC type_prop/adaptive_avg_pool.cpp type_prop/adaptive_max_pool.cpp type_prop/asin.cpp + type_prop/asinh.cpp type_prop/assign.cpp type_prop/atan.cpp type_prop/avg_pool.cpp @@ -231,6 +232,7 @@ set(SRC visitors/value_map.cpp visitors/op/adaptive_avg_pool.cpp visitors/op/adaptive_max_pool.cpp + visitors/op/asinh.cpp visitors/op/atan.cpp visitors/op/batch_norm.cpp visitors/op/batch_to_space.cpp diff --git a/ngraph/test/backend/asinh.in.cpp b/ngraph/test/backend/asinh.in.cpp index 5cde50b53bb..d3e8fe44c88 100644 --- a/ngraph/test/backend/asinh.in.cpp +++ b/ngraph/test/backend/asinh.in.cpp @@ -49,3 +49,18 @@ NGRAPH_TEST(${BACKEND_NAME}, asinh) test_case.add_expected_output(shape, expected); test_case.run(); } + +NGRAPH_TEST(${BACKEND_NAME}, asinh_i32) +{ + Shape shape{11}; + auto A = make_shared(element::i32, shape); + auto f = make_shared(make_shared(A), ParameterVector{A}); + + vector input{-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5}; + vector expected{-2, -2, -2, -1, -1, 0, 1, 1, 2, 2, 2}; + + auto test_case = test::TestCase(f); + test_case.add_input(input); + test_case.add_expected_output(shape, expected); + test_case.run(); +} diff --git a/ngraph/test/type_prop/asinh.cpp b/ngraph/test/type_prop/asinh.cpp new file mode 100644 index 00000000000..e6592a35b81 --- /dev/null +++ b/ngraph/test/type_prop/asinh.cpp @@ -0,0 +1,9 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "unary_ops.hpp" + +using Type = ::testing::Types; + +INSTANTIATE_TYPED_TEST_SUITE_P(type_prop_asinh, UnaryOperator, Type); diff --git a/ngraph/test/visitors/op/asinh.cpp b/ngraph/test/visitors/op/asinh.cpp new file mode 100644 index 00000000000..6e18ede91c8 --- /dev/null +++ b/ngraph/test/visitors/op/asinh.cpp @@ -0,0 +1,11 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "unary_ops.hpp" +using Type = ::testing::Types>; + +INSTANTIATE_TYPED_TEST_SUITE_P(visitor_without_attribute, + UnaryOperatorVisitor, + Type, + UnaryOperatorTypeName); \ No newline at end of file From a4fef45e0c5f2b3a37743a1045a4cfaae7c73759 Mon Sep 17 00:00:00 2001 From: Gabriele Galiero Casay Date: Thu, 8 Jul 2021 06:47:01 +0200 Subject: [PATCH 02/13] Enable lower input rank for BatchToSpace operation by fallback (#6553) * Enable lower input rank for BatchToSpace operation by fallback * Added conditions to check valid data input rank for evaluate and has_evaluate methods --- .../single_layer_tests/batch_to_space.cpp | 51 +++++++++++++++---- ngraph/core/src/op/batch_to_space.cpp | 9 ++-- ngraph/test/backend/batch_to_space.in.cpp | 21 ++++++++ ngraph/test/type_prop/batch_to_space.cpp | 40 ++++++++++----- ngraph/test/visitors/op/batch_to_space.cpp | 8 +-- 5 files changed, 99 insertions(+), 30 deletions(-) diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/batch_to_space.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/batch_to_space.cpp index cd81911f707..0ebf53d7bed 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/batch_to_space.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/batch_to_space.cpp @@ -16,6 +16,39 @@ const std::vector net_precisions = { InferenceEngine::Precision::I32 }; +const std::vector> data_shapes_2D = { + {12, 4}, + {48, 3} +}; + +const std::vector> block_shapes_2D = { + {1, 2}, + {1, 6} +}; + +const std::vector> crops_2D = { + {0, 0}, + {0, 1} +}; + +const auto batch_to_space_2d_tests = ::testing::Combine( + ::testing::ValuesIn(block_shapes_2D), + ::testing::ValuesIn(crops_2D), + ::testing::ValuesIn(crops_2D), + ::testing::ValuesIn(data_shapes_2D), + ::testing::ValuesIn(net_precisions), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(CommonTestUtils::DEVICE_CPU)); + +INSTANTIATE_TEST_CASE_P( + smoke_BatchToSpace_2D, + BatchToSpaceLayerTest, + batch_to_space_2d_tests, + BatchToSpaceLayerTest::getTestCaseName); + const std::vector> data_shapes_4D = { {4, 1, 2, 2}, {4, 3, 2, 2}, @@ -39,7 +72,7 @@ const std::vector> crops_end_4D = { {0, 0, 0, 2} }; -const auto space_to_batch_4d_spatial_dims_tests = ::testing::Combine( +const auto batch_to_space_4d_spatial_dims_tests = ::testing::Combine( ::testing::Values(block_shapes_4D[0]), ::testing::ValuesIn(crops_begin_4D), ::testing::ValuesIn(crops_end_4D), @@ -51,7 +84,7 @@ const auto space_to_batch_4d_spatial_dims_tests = ::testing::Combine( ::testing::Values(InferenceEngine::Layout::ANY), ::testing::Values(CommonTestUtils::DEVICE_CPU)); -const auto space_to_batch_4d_channel_dim_tests = ::testing::Combine( +const auto batch_to_space_4d_channel_dim_tests = ::testing::Combine( ::testing::Values(block_shapes_4D[1]), ::testing::Values(crops_begin_4D[0]), ::testing::Values(crops_end_4D[0]), @@ -66,13 +99,13 @@ const auto space_to_batch_4d_channel_dim_tests = ::testing::Combine( INSTANTIATE_TEST_CASE_P( smoke_BatchToSpace_4D_spatial_dims, BatchToSpaceLayerTest, - space_to_batch_4d_spatial_dims_tests, + batch_to_space_4d_spatial_dims_tests, BatchToSpaceLayerTest::getTestCaseName); INSTANTIATE_TEST_CASE_P( smoke_BatchToSpace_4D_channel_dim, BatchToSpaceLayerTest, - space_to_batch_4d_channel_dim_tests, + batch_to_space_4d_channel_dim_tests, BatchToSpaceLayerTest::getTestCaseName); const std::vector> data_shapes_5D = { @@ -96,7 +129,7 @@ const std::vector> crops_end_5D = { {0, 0, 0, 0, 1} }; -const auto space_to_batch_5d_spatial_dims_tests = ::testing::Combine( +const auto batch_to_space_5d_spatial_dims_tests = ::testing::Combine( ::testing::Values(block_shapes_5D[0]), ::testing::ValuesIn(crops_begin_5D), ::testing::ValuesIn(crops_end_5D), @@ -108,7 +141,7 @@ const auto space_to_batch_5d_spatial_dims_tests = ::testing::Combine( ::testing::Values(InferenceEngine::Layout::ANY), ::testing::Values(CommonTestUtils::DEVICE_CPU)); -const auto space_to_batch_5d_channel_dim_tests = ::testing::Combine( +const auto batch_to_space_5d_channel_dim_tests = ::testing::Combine( ::testing::Values(block_shapes_5D[1]), ::testing::Values(crops_begin_5D[0]), ::testing::Values(crops_end_5D[0]), @@ -123,13 +156,13 @@ const auto space_to_batch_5d_channel_dim_tests = ::testing::Combine( INSTANTIATE_TEST_CASE_P( smoke_BatchToSpace_5D_spatial_dims, BatchToSpaceLayerTest, - space_to_batch_5d_spatial_dims_tests, + batch_to_space_5d_spatial_dims_tests, BatchToSpaceLayerTest::getTestCaseName); INSTANTIATE_TEST_CASE_P( smoke_BatchToSpace_5D_channel_dim, BatchToSpaceLayerTest, - space_to_batch_5d_channel_dim_tests, + batch_to_space_5d_channel_dim_tests, BatchToSpaceLayerTest::getTestCaseName); -} // namespace \ No newline at end of file +} // namespace diff --git a/ngraph/core/src/op/batch_to_space.cpp b/ngraph/core/src/op/batch_to_space.cpp index 8e2e98553cf..9ec3c0f7bd1 100644 --- a/ngraph/core/src/op/batch_to_space.cpp +++ b/ngraph/core/src/op/batch_to_space.cpp @@ -88,8 +88,8 @@ void op::v1::BatchToSpace::validate_and_infer_types() if (data_rank.is_static()) { NODE_VALIDATION_CHECK(this, - (data_rank.get_length() >= 4), - "data input must have rank greater than or equal to 4. Got: ", + (data_rank.get_length() >= 2), + "data input must have rank greater or equal than 2. Got: ", data_rank.get_length()); if (inputs_same_ps.is_static()) @@ -197,7 +197,7 @@ namespace } auto data_shape = data->get_shape(); auto data_rank = data_shape.size(); - if (!(data_rank == 4 || data_rank == 5)) + if (data_rank < 2) { return false; } @@ -346,7 +346,6 @@ bool ngraph::op::v1::BatchToSpace::evaluate(const HostTensorVector& outputs, bool ngraph::op::v1::BatchToSpace::has_evaluate() const { NGRAPH_OP_SCOPE(v1_BatchToSpace_has_evaluate); - return !get_input_partial_shape(0).is_dynamic() && - (get_input_shape(0).size() == 4 || get_input_shape(0).size() == 5) && + return !get_input_partial_shape(0).is_dynamic() && get_input_shape(0).size() >= 2 && get_input_shape(0).size() <= shape_size(get_input_shape(1)); } diff --git a/ngraph/test/backend/batch_to_space.in.cpp b/ngraph/test/backend/batch_to_space.in.cpp index ac6f07e3002..91fbbafed53 100644 --- a/ngraph/test/backend/batch_to_space.in.cpp +++ b/ngraph/test/backend/batch_to_space.in.cpp @@ -79,6 +79,27 @@ NGRAPH_TEST_P(${BACKEND_NAME}, BatchToSpaceTestFloat, BatchToSpaceTestFloatCases BatchToSpaceTestExecute(GetParam()); } +const test::NDArray input_with_shape_4x3( + {{1.0f, 2.0f, 3.0f}, + {4.0f, 5.0f, 6.0f}, + {7.0f, 8.0f, 9.0f}, + {10.0f, 11.0f, 12.0f}}); + +const test::NDArray zero_crops_2d({0, 0}); + +NGRAPH_INSTANTIATE_TEST_SUITE_P( + ${BACKEND_NAME}, + batch_to_space_2d_without_crops, + BatchToSpaceTestFloat, + testing::Values( + BatchToSpaceParams{input_with_shape_4x3, + test::NDArray({1, 2}), + zero_crops_2d, + zero_crops_2d, + test::NDArray( + {{1.0f, 7.0f, 2.0f, 8.0f, 3.0f, 9.0f}, + {4.0f, 10.0f, 5.0f, 11.0f, 6.0f, 12.0f}})})); + const test::NDArray input_with_shape_4x1x1x3( {{{{1.0f, 2.0f, 3.0f}}}, {{{4.0f, 5.0f, 6.0f}}}, diff --git a/ngraph/test/type_prop/batch_to_space.cpp b/ngraph/test/type_prop/batch_to_space.cpp index c324e72e270..54dfd3bfd98 100644 --- a/ngraph/test/type_prop/batch_to_space.cpp +++ b/ngraph/test/type_prop/batch_to_space.cpp @@ -49,8 +49,8 @@ TEST(type_prop, batch_to_space_incompatible_input_element_types) element::Type integer64_et = element::i64; element::Type integer32_et = element::i32; - Shape data_sshape{10, 26, 4, 4}; - Shape inputs_sshape{4}; + Shape data_sshape{10, 26}; + Shape inputs_sshape{2}; vector test_cases; test_cases.push_back( @@ -97,8 +97,8 @@ TEST(type_prop, batch_to_space_invalid_input_element_types) { element::Type float_et = element::f32; - Shape data_sshape{10, 26, 4, 4}; - Shape inputs_sshape{4}; + Shape data_sshape{10, 26}; + Shape inputs_sshape{2}; const BatchToSpaceInputParams params{ InputInfo{float_et, data_sshape}, @@ -124,7 +124,7 @@ TEST(type_prop, batch_to_space_invalid_input_element_types) TEST(type_prop, batch_to_space_invalid_data_input_rank) { - Shape data_sshape{4, 2}; + Shape data_sshape{4}; element::Type data_et = element::f32; Shape inputs_sshape{2}; @@ -143,7 +143,7 @@ TEST(type_prop, batch_to_space_invalid_data_input_rank) } catch(const NodeValidationFailure& error) { - EXPECT_HAS_SUBSTRING(error.what(), "data input must have rank greater than or equal to 4"); + EXPECT_HAS_SUBSTRING(error.what(), "data input must have rank greater or equal than 2."); } catch (...) { @@ -153,11 +153,11 @@ TEST(type_prop, batch_to_space_invalid_data_input_rank) TEST(type_prop, batch_to_space_incompatible_secondary_inputs_shapes) { - Shape data_sshape{10, 26, 4, 4}; + Shape data_sshape{10, 26}; element::Type data_et = element::f32; - Shape inputs_sshape_1D{4}; - Shape inputs_sshape_2D{4, 1}; + Shape inputs_sshape_1D{2}; + Shape inputs_sshape_2D{2, 1}; element::Type inputs_et = element::i64; vector test_cases; @@ -203,10 +203,10 @@ TEST(type_prop, batch_to_space_incompatible_secondary_inputs_shapes) TEST(type_prop, batch_to_space_invalid_secondary_inputs_rank) { - Shape data_sshape{10, 26, 4, 4}; + Shape data_sshape{10, 26}; element::Type data_et = element::f32; - Shape inputs_sshape_2D{4, 1}; + Shape inputs_sshape_2D{2, 1}; element::Type inputs_et = element::i64; const BatchToSpaceInputParams params{ @@ -233,7 +233,7 @@ TEST(type_prop, batch_to_space_invalid_secondary_inputs_rank) TEST(type_prop, batch_to_space_incompatible_data_and_secondary_inputs_shapes) { - Shape data_sshape{10, 26, 4, 4}; + Shape data_sshape{10, 26}; element::Type data_et = element::f32; Shape inputs_sshape{5}; @@ -414,6 +414,22 @@ TEST(type_prop, batch_to_space_invalid_crops_out_of_bounds) } } +TEST(type_prop, batch_to_space_output_shape_2D) +{ + auto data = make_shared(element::f32, Shape{10, 26}); + auto block_shape = + make_shared(element::i64, Shape{2}, vector{1, 5}); + auto crops_begin = + make_shared(element::i64, Shape{2}, vector{0, 2}); + auto crops_end = + make_shared(element::i64, Shape{2}, vector{0, 0}); + auto batch_to_space = + make_shared(data, block_shape, crops_begin, crops_end); + + ASSERT_EQ(batch_to_space->get_element_type(), element::f32); + ASSERT_EQ(batch_to_space->get_shape(), (Shape{10 / 5, 26 * 5 - 2})); +} + TEST(type_prop, batch_to_space_output_shape_4D) { auto data = make_shared(element::f32, Shape{100, 7, 13, 3}); diff --git a/ngraph/test/visitors/op/batch_to_space.cpp b/ngraph/test/visitors/op/batch_to_space.cpp index 7e200bacafc..60f653283bf 100644 --- a/ngraph/test/visitors/op/batch_to_space.cpp +++ b/ngraph/test/visitors/op/batch_to_space.cpp @@ -16,10 +16,10 @@ using ngraph::test::NodeBuilder; TEST(attributes, batch_to_space_op) { NodeBuilder::get_ops().register_factory(); - auto data = make_shared(element::f32, Shape{128, 4, 2, 2}); - auto block_shape = make_shared(element::i64, Shape{4}, vector{1, 2, 2, 2}); - auto crops_begin = make_shared(element::i64, Shape{4}, vector{0, 2, 0, 1}); - auto crops_end = make_shared(element::i64, Shape{4}, vector{0, 0, 1, 0}); + auto data = make_shared(element::f32, Shape{2, 128}); + auto block_shape = make_shared(element::i64, Shape{2}, vector{1, 2}); + auto crops_begin = make_shared(element::i64, Shape{2}, vector{0, 2}); + auto crops_end = make_shared(element::i64, Shape{2}, vector{0, 0}); auto batch2space = make_shared(data, block_shape, crops_begin, crops_end); NodeBuilder builder(batch2space); From e63b7dc39c71c6696c9102c85035060258e75d47 Mon Sep 17 00:00:00 2001 From: Gabriele Galiero Casay Date: Thu, 8 Jul 2021 06:50:29 +0200 Subject: [PATCH 03/13] BatchToSpace specification refactoring (#6528) * BatchToSpace specification refactored * Add minor changes * Added \ldots to latex formula * Change output tensor to lower-case y * Added mention to reverse operation SpaceToBatch * Corrected dots in formulas * Enable rank greater or equal than 2 for data input and add more examples * Minor changes in detailed description * Improve short and detailed descriptions --- docs/ops/movement/BatchToSpace_2.md | 83 +++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 21 deletions(-) diff --git a/docs/ops/movement/BatchToSpace_2.md b/docs/ops/movement/BatchToSpace_2.md index 936d597792e..85fdd781f68 100644 --- a/docs/ops/movement/BatchToSpace_2.md +++ b/docs/ops/movement/BatchToSpace_2.md @@ -4,46 +4,87 @@ **Category**: *Data movement* -**Short description**: The *BatchToSpace* operation reshapes the "batch" dimension 0 into N - 1 dimensions of shape `block_shape` + [batch] and interleaves these blocks back into the grid defined by the spatial dimensions `[1, ..., N - 1]` to obtain a result with the same rank as `data` input. The spatial dimensions of this intermediate result are then optionally cropped according to `crops_begin` and `crops_end` to produce the output. This is the reverse of the *SpaceToBatch* operation. +**Short description**: *BatchToSpace* operation permutes the batch dimension on a given input `data` into blocks in the spatial dimensions specified by `block_shape` input. The spatial dimensions are then optionally cropped according to `crops_begin` and `crops_end` inputs to produce the output. -**Detailed description**: +**Detailed description** -The *BatchToSpace* operation is similar to the TensorFlow* operation [BatchToSpaceND](https://www.tensorflow.org/api_docs/python/tf/batch_to_space_nd) +*BatchToSpace* operation is equivalent to the following operation steps on the input `data` with shape `[batch, D_1, D_2, ..., D_{N-1}]` and `block_shape`, `crops_begin`, `crops_end` inputs with shape `[N]` to produce the output tensor \f$y\f$. -The operation is equivalent to the following transformation of the input tensors `data` with shape `[batch, D_1, D_2 ... D_{N-1}]` and `block_shape`, `crops_begin`, `crops_end` of shape `[N]` to *Y* output tensor. +1. Reshape `data` input to produce a tensor of shape \f$[B_1, \dots, B_{N - 1}, \frac{batch}{\left(B_1 \times \dots \times B_{N - 1}\right)}, D_1, D_2, \dots, D_{N - 1}]\f$ +\f[x^{\prime} = reshape(data, [B_1, \dots, B_{N - 1}, \frac{batch}{\left(B_1 \times \dots \times B_{N - 1}\right)}, D_1, D_2, \dots, D_{N - 1}])\f] - note: B_0 is expected to be 1. - x' = reshape(`data`, [B_1, ..., B_{N - 1}, batch / (B_1 * ... B_{N - 1}), D_1, D_2, ..., D_{N - 1}]), where B_i = block_shape[i] +2. Permute dimensions of \f$x^{\prime}\f$ to produce a tensor of shape \f$[\frac{batch}{\left(B_1 \times \dots \times B_{N - 1}\right)}, D_1, B_1, D_2, B_2, \dots, D_{N-1}, B_{N - 1}]\f$ +\f[x^{\prime\prime} = transpose(x', [N, N + 1, 0, N + 2, 1, \dots, N + N - 1, N - 1])\f] - x'' = transpose(x', [N, N + 1, 0, N + 2, 1, ..., N + N - 1, N - 1]) +3. Reshape \f$x^{\prime\prime}\f$ to produce a tensor of shape \f$[\frac{batch}{\left(B_1 \times \dots \times B_{N - 1}\right)}, D_1 \times B_1, D_2 \times B_2, \dots, D_{N - 1} \times B_{N - 1}]\f$ +\f[x^{\prime\prime\prime} = reshape(x^{\prime\prime}, [\frac{batch}{\left(B_1 \times \dots \times B_{N - 1}\right)}, D_1 \times B_1, D_2 \times B_2, \dots, D_{N - 1} \times B_{N - 1}])\f] - x''' = reshape(x'', [batch / (B_1 * ... * B_{N - 1}), D_1 * B_1, D_2 * B_2, ... , D_{N - 1} * B_{N - 1}]) +4. Crop the start and end of spatial dimensions of \f$x^{\prime\prime\prime}\f$ according to `crops_begin` and `crops_end` inputs to produce the output \f$y\f$ of shape: +\f[\left[\frac{batch}{\left(B_1 \times \dots \times B_{N - 1}\right)}, crop(D_1 \times B_1, CB_1, CE_1), crop(D_2 \times B_2, CB_2, CE_2), \dots , crop(D_{N - 1} \times B_{N - 1}, CB_{N - 1}, CE_{N - 1})\right]\f] - Crop the start and end of dimensions according to `crops_begin`, `crops_end` to produce the output of shape: - note: `crops_begin[0], crops_end[0]` are expected to be 0. - `y = [batch / (B_1 * ... * B_{N - 1}), crop(D_1 * B_1, crops_begin[1], crops_end[1]), crop(D_2 * B_2, crops_begin[2], crops_end[2]), ... , crop(D_{N - 1} * B_{N - 1}, crops_begin[N - 1], crops_end[N - 1])]` +Where -**Attributes** +- \f$B_i\f$ = block_shape[i] +- \f$B_0\f$ is expected to be 1 +- \f$CB_i\f$ = crops_begin[i] +- \f$CE_i\f$ = crops_end[i] +- \f$CB_0\f$ and \f$CE_0\f$ are expected to be 0 +- \f$CB_i + CE_i \leq D_i \times B_i \f$ - No attributes available. +*BatchToSpace* operation is the reverse of *SpaceToBatch* operation. + +**Attributes**: *BatchToSpace* operation has no attributes. **Inputs** -* **1**: `data` - input N-D tensor `[batch, D_1, D_2 ... D_{N-1}]` of *T1* type with rank >= 2. **Required.** -* **2**: `block_shape` - input 1-D tensor of *T2* type with shape `[N]` that is equal to the size of `data` input shape. All values must be >= 1.`block_shape[0]` is expected to be 1. **Required.** -* **3**: `crops_begin` - input 1-D tensor of *T2* type with shape `[N]` that is equal to the size of `data` input shape. All values must be non-negative. crops_begin specifies the amount to crop from the beginning along each axis of `data` input . It is required that `crop_start[i] + crop_end[i] <= block_shape[i] * input_shape[i]`. `crops_begin[0]` is expected to be 0. **Required.** -* **4**: `crops_end` - input 1-D tensor of *T2* type with shape `[N]` that is equal to the size of `data` input shape. All values must be non-negative. crops_end specifies the amount to crop from the ending along each axis of `data` input. It is required that `crop_start[i] + crop_end[i] <= block_shape[i] * input_shape[i]`. `crops_end[0]` is expected to be 0. **Required.** +* **1**: `data` - A tensor of type *T* and rank greater than or equal to 2. Layout is `[batch, D_1, D_2 ... D_{N-1}]` (number of batches, spatial axes). **Required.** +* **2**: `block_shape` - Specifies the block sizes of `batch` axis of `data` input which are moved to the corresponding spatial axes. A 1D tensor of type *T_INT* and shape `[N]`. All element values must be greater than or equal to 1.`block_shape[0]` is expected to be 1. **Required.** +* **3**: `crops_begin` - Specifies the amount to crop from the beginning along each axis of `data` input. A 1D tensor of type *T_INT* and shape `[N]`. All element values must be greater than or equal to 0. `crops_begin[0]` is expected to be 0. **Required.** +* **4**: `crops_end` - Specifies the amount to crop from the ending along each axis of `data` input. A 1D tensor of type *T_INT* and shape `[N]`. All element values must be greater than or equal to 0. `crops_end[0]` is expected to be 0. **Required.** +* **Note**: `N` corresponds to the rank of `data` input. +* **Note**: `batch` axis of `data` input must be evenly divisible by the cumulative product of `block_shape` elements. +* **Note**: It is required that `crops_begin[i] + crops_end[i] <= block_shape[i] * input_shape[i]`. **Outputs** -* **1**: N-D tensor with shape `[batch / (block_shape[0] * block_shape[1] * ... * block_shape[N - 1]), D_1 * block_shape[1] - crops_begin[1] - crops_end[1], D_2 * block_shape[2] - crops_begin[2] - crops_end[2], ..., D_{N - 1} * block_shape[N - 1] - crops_begin[N - 1] - crops_end[N - 1]` of the same type as `data` input. +* **1**: Permuted tensor of type *T* with the same rank as `data` input tensor, and shape `[batch / (block_shape[0] * block_shape[1] * ... * block_shape[N - 1]), D_1 * block_shape[1] - crops_begin[1] - crops_end[1], D_2 * block_shape[2] - crops_begin[2] - crops_end[2], ..., D_{N - 1} * block_shape[N - 1] - crops_begin[N - 1] - crops_end[N - 1]`. **Types** -* *T1*: any supported type. -* *T2*: any supported integer type. +* *T*: any supported type. +* *T_INT*: any supported integer type. -**Example** +**Examples** + +*Example: 2D input tensor `data`* + +```xml + + + + 10 + 2 + + + 2 + + + 2 + + + 2 + + + + + 2 + 8 + + + +``` + +*Example: 5D input tensor `data`* ```xml From 23f4bf4e70d57396cd012c0d4bb226d960ba7c9c Mon Sep 17 00:00:00 2001 From: Ilya Churaev Date: Thu, 8 Jul 2021 08:01:40 +0300 Subject: [PATCH 04/13] Removed legacy tests (#6558) --- ngraph/core/include/ngraph/slice_plan.hpp | 2 +- ngraph/test/CMakeLists.txt | 3 - ngraph/test/dyn_elimination.cpp | 142 -- ngraph/test/op_is.cpp | 577 ----- ngraph/test/pass_liveness.cpp | 49 - ngraph/test/pass_shape_relevance.cpp | 171 -- ngraph/test/provenance.cpp | 56 - ngraph/test/runtime/CMakeLists.txt | 18 - .../test/runtime/dynamic/dynamic_backend.cpp | 4 - ngraph/test/runtime/ie/ie_executable.cpp | 12 +- .../runtime/interpreter/int_executable.hpp | 1 - ngraph/test/runtime/op/atan2.cpp | 34 - ngraph/test/runtime/op/atan2.hpp | 43 - ngraph/test/runtime/op/avg_pool.cpp | 235 -- ngraph/test/runtime/op/avg_pool.hpp | 164 -- ngraph/test/runtime/op/convolution.cpp | 343 --- ngraph/test/runtime/op/convolution.hpp | 304 --- ngraph/test/runtime/op/group_conv.cpp | 319 --- ngraph/test/runtime/op/group_conv.hpp | 131 - ngraph/test/runtime/opset0_tbl.hpp | 101 - .../runtime/pass/fused_op_decomposition.cpp | 80 - .../runtime/pass/fused_op_decomposition.hpp | 67 - .../pass/implicit_broadcast_elimination.cpp | 61 - .../pass/implicit_broadcast_elimination.hpp | 28 - ngraph/test/runtime/pass/liveness.cpp | 119 - ngraph/test/runtime/pass/liveness.hpp | 23 - ngraph/test/runtime/pass/opset0_downgrade.cpp | 132 - ngraph/test/runtime/pass/opset0_downgrade.hpp | 31 - ngraph/test/runtime/pass/opset1_downgrade.cpp | 128 - ngraph/test/runtime/pass/opset1_downgrade.hpp | 31 - ngraph/test/runtime/pass/opset1_upgrade.cpp | 222 -- ngraph/test/runtime/pass/opset1_upgrade.hpp | 31 - ngraph/test/tensor.cpp | 61 - ngraph/test/type_prop/convolution.cpp | 2229 ----------------- .../type_prop/convolution_backprop_data.cpp | 283 +-- ngraph/test/util/engine/ie_engines.cpp | 28 +- ngraph/test/util/engine/ie_engines.hpp | 9 +- 37 files changed, 32 insertions(+), 6240 deletions(-) delete mode 100644 ngraph/test/dyn_elimination.cpp delete mode 100644 ngraph/test/op_is.cpp delete mode 100644 ngraph/test/pass_liveness.cpp delete mode 100644 ngraph/test/pass_shape_relevance.cpp delete mode 100644 ngraph/test/runtime/op/atan2.cpp delete mode 100644 ngraph/test/runtime/op/atan2.hpp delete mode 100644 ngraph/test/runtime/op/avg_pool.cpp delete mode 100644 ngraph/test/runtime/op/avg_pool.hpp delete mode 100644 ngraph/test/runtime/op/convolution.cpp delete mode 100644 ngraph/test/runtime/op/convolution.hpp delete mode 100644 ngraph/test/runtime/op/group_conv.cpp delete mode 100644 ngraph/test/runtime/op/group_conv.hpp delete mode 100644 ngraph/test/runtime/opset0_tbl.hpp delete mode 100644 ngraph/test/runtime/pass/fused_op_decomposition.cpp delete mode 100644 ngraph/test/runtime/pass/fused_op_decomposition.hpp delete mode 100644 ngraph/test/runtime/pass/implicit_broadcast_elimination.cpp delete mode 100644 ngraph/test/runtime/pass/implicit_broadcast_elimination.hpp delete mode 100644 ngraph/test/runtime/pass/liveness.cpp delete mode 100644 ngraph/test/runtime/pass/liveness.hpp delete mode 100644 ngraph/test/runtime/pass/opset0_downgrade.cpp delete mode 100644 ngraph/test/runtime/pass/opset0_downgrade.hpp delete mode 100644 ngraph/test/runtime/pass/opset1_downgrade.cpp delete mode 100644 ngraph/test/runtime/pass/opset1_downgrade.hpp delete mode 100644 ngraph/test/runtime/pass/opset1_upgrade.cpp delete mode 100644 ngraph/test/runtime/pass/opset1_upgrade.hpp diff --git a/ngraph/core/include/ngraph/slice_plan.hpp b/ngraph/core/include/ngraph/slice_plan.hpp index cc26285fd32..6a1ac2dde03 100644 --- a/ngraph/core/include/ngraph/slice_plan.hpp +++ b/ngraph/core/include/ngraph/slice_plan.hpp @@ -12,7 +12,7 @@ namespace ngraph { // - // In various places, like ConstantFolding and DynElimination, it is + // In various places, like ConstantFolding, it is // useful to transform DynSlice by converting it to a sequence of ops: // // Slice (to do the basic slicing) diff --git a/ngraph/test/CMakeLists.txt b/ngraph/test/CMakeLists.txt index d016bbd245c..9d608f986e9 100644 --- a/ngraph/test/CMakeLists.txt +++ b/ngraph/test/CMakeLists.txt @@ -75,13 +75,10 @@ set(SRC op_eval/strided_slice.cpp op_eval/transpose.cpp op_eval/variadic_split.cpp - op_is.cpp opset1.cpp partial_shape.cpp pass_config.cpp - pass_liveness.cpp pass_manager.cpp - pass_shape_relevance.cpp pattern.cpp provenance.cpp replace_node.cpp diff --git a/ngraph/test/dyn_elimination.cpp b/ngraph/test/dyn_elimination.cpp deleted file mode 100644 index 14a64c1d80b..00000000000 --- a/ngraph/test/dyn_elimination.cpp +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "gtest/gtest.h" - -#include "ngraph/ngraph.hpp" -#include "ngraph/pass/constant_folding.hpp" -#include "ngraph/pass/dyn_elimination.hpp" -#include "ngraph/pass/manager.hpp" -#include "pass/opset0_downgrade.hpp" -#include "util/all_close_f.hpp" -#include "util/test_tools.hpp" - -using namespace ngraph; -using namespace std; - -TEST(dyn_elimination, transpose) -{ - Shape shape_in{2, 4, 6, 8}; - auto param = make_shared(element::boolean, shape_in); - - auto constant_perm = - make_shared(element::i64, Shape{4}, vector{2, 3, 1, 0}); - - auto transpose = make_shared(param, constant_perm); - - auto f = make_shared(transpose, ParameterVector{param}); - - pass::Manager pass_manager; - pass_manager.register_pass(); - pass_manager.run_passes(f); - - ASSERT_EQ(count_ops_of_type(f), 0); - ASSERT_EQ(count_ops_of_type(f), 1); - - auto new_reshape = - as_type_ptr(f->get_results().at(0)->input_value(0).get_node_shared_ptr()); - ASSERT_TRUE(new_reshape); - - ASSERT_EQ(new_reshape->get_input_order(), (AxisVector{2, 3, 1, 0})); - ASSERT_EQ(new_reshape->get_output_shape(0), (Shape{6, 8, 4, 2})); - ASSERT_EQ(new_reshape->get_output_element_type(0), element::boolean); -} - -// For now, we can't handle the case where the input has dynamic shapes, -// because the classic Reshape op demands a Shape. Probably won't be able to -// deal with this until/unless we make a "StaticTranspose". Just make sure -// we don't crash or mangle the graph. -TEST(dyn_elimination, transpose_dyn_shape) -{ - PartialShape shape_in{2, 4, Dimension::dynamic(), 8}; - - auto param = make_shared(element::boolean, shape_in); - - auto constant_perm = - make_shared(element::i64, Shape{4}, vector{2, 3, 1, 0}); - - auto transpose = make_shared(param, constant_perm); - - auto f = make_shared(transpose, ParameterVector{param}); - - pass::Manager pass_manager; - pass_manager.register_pass(); - pass_manager.run_passes(f); - - ASSERT_EQ(count_ops_of_type(f), 1); - ASSERT_EQ(count_ops_of_type(f), 1); - - auto new_transpose = - as_type_ptr(f->get_results().at(0)->input_value(0).get_node_shared_ptr()); - ASSERT_TRUE(new_transpose); - - ASSERT_EQ(new_transpose->get_output_element_type(0), element::boolean); - ASSERT_TRUE(new_transpose->get_output_partial_shape(0).relaxes( - PartialShape{Dimension::dynamic(), 8, 4, 2})); -} - -TEST(dyn_elimination, range) -{ - auto constant_start = make_shared(element::i64, Shape{}, vector{0}); - auto constant_stop = make_shared(element::i64, Shape{}, vector{5}); - auto constant_step = make_shared(element::i64, Shape{}, vector{2}); - - auto range = make_shared(constant_start, constant_stop, constant_step); - - ASSERT_EQ(range->get_element_type(), element::i64); - ASSERT_EQ(range->get_shape(), (Shape{3})); - - auto f = make_shared(range, ParameterVector{}); - - pass::Manager pass_manager; - pass_manager.register_pass(); - pass_manager.run_passes(f); - - ASSERT_EQ(count_ops_of_type(f), 0); - ASSERT_EQ(count_ops_of_type(f), 1); - - auto replacement = - as_type_ptr(f->get_results().at(0)->input_value(0).get_node_shared_ptr()); - - ASSERT_NE(replacement, nullptr); - ASSERT_EQ(replacement->get_element_type(), element::i64); - ASSERT_EQ(replacement->get_shape(), (Shape{3})); - - auto vals = replacement->get_vector(); - - ASSERT_EQ(vals, (vector{0, 2, 4})); -} - -TEST(dyn_elimination, range_f64) -{ - auto constant_start = make_shared(element::f64, Shape{}, vector{-0.5}); - auto constant_stop = make_shared(element::f64, Shape{}, vector{2}); - auto constant_step = make_shared(element::f64, Shape{}, vector{0.25}); - - auto range = make_shared(constant_start, constant_stop, constant_step); - - ASSERT_EQ(range->get_element_type(), element::f64); - ASSERT_EQ(range->get_shape(), (Shape{10})); - - auto f = make_shared(range, ParameterVector{}); - - pass::Manager pass_manager; - pass_manager.register_pass(); - pass_manager.run_passes(f); - - ASSERT_EQ(count_ops_of_type(f), 0); - ASSERT_EQ(count_ops_of_type(f), 1); - - auto replacement = - as_type_ptr(f->get_results().at(0)->input_value(0).get_node_shared_ptr()); - - ASSERT_NE(replacement, nullptr); - ASSERT_EQ(replacement->get_element_type(), element::f64); - ASSERT_EQ(replacement->get_shape(), (Shape{10})); - - auto vals = replacement->get_vector(); - - ASSERT_TRUE(test::all_close_f( - vals, vector{-0.5, -0.25, 0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75})); -} diff --git a/ngraph/test/op_is.cpp b/ngraph/test/op_is.cpp deleted file mode 100644 index a3f81b3d800..00000000000 --- a/ngraph/test/op_is.cpp +++ /dev/null @@ -1,577 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "gtest/gtest.h" - -#include "ngraph/ngraph.hpp" -#include "ngraph/op/util/op_types.hpp" -#include "ngraph/validation_util.hpp" -#include "op/convolution.hpp" -#include "op/group_conv.hpp" -#include "util/test_tools.hpp" - -using namespace ngraph; - -NGRAPH_SUPPRESS_DEPRECATED_START - -namespace -{ - void op_is_Abs() - { - op::Abs node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Acos() - { - op::Acos node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Asin() - { - op::Asin node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Atan() - { - op::Atan node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_AvgPool() - { - op::AvgPool node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_BatchNormInference() - { - op::v0::BatchNormInference node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Broadcast() - { - op::v1::Broadcast node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Ceiling() - { - op::Ceiling node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Clamp() - { - op::Clamp node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Concat() - { - op::Concat node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Constant() - { - op::Constant node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Convert() - { - op::Convert node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Convolution() - { - op::v0::Convolution node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_ConvolutionBackpropData() - { - op::v0::ConvolutionBackpropData node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Cos() - { - op::Cos node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Cosh() - { - op::Cosh node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_CumSum() - { - op::CumSum node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_DepthToSpace() - { - op::DepthToSpace node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Elu() - { - op::Elu node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Erf() - { - op::Erf node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Exp() - { - op::Exp node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_FakeQuantize() - { - op::FakeQuantize node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Floor() - { - op::Floor node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_GRN() - { - op::GRN node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Gather() - { - op::v1::Gather node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Gelu() - { - op::Gelu node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_GroupConvolution() - { - op::v0::GroupConvolution node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_GroupConvolutionBackpropData() - { - op::v0::GroupConvolutionBackpropData node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_HardSigmoid() - { - op::HardSigmoid node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Interpolate() - { - op::v0::Interpolate node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Log() - { - op::Log node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_LRN() - { - op::LRN node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_LSTMSequence() - { - op::v0::LSTMSequence node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_MatMul() - { - op::MatMul node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_NormalizeL2() - { - op::v0::NormalizeL2 node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_MVN() - { - op::MVN node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Negative() - { - op::Negative node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Parameter() - { - op::Parameter node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_PRelu() - { - op::PRelu node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_PriorBox() - { - op::PriorBox node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Range() - { - op::Range node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Relu() - { - op::Relu node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Result() - { - op::Result node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_ReverseSequence() - { - op::ReverseSequence node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Selu() - { - op::Selu node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_ShapeOf() - { - op::ShapeOf node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_ShuffleChannels() - { - op::ShuffleChannels node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Sigmoid() - { - op::Sigmoid node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Sign() - { - op::Sign node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Sin() - { - op::Sin node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Sinh() - { - op::Sinh node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_SpaceToDepth() - { - op::SpaceToDepth node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Sqrt() - { - op::Sqrt node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_SquaredDifference() - { - op::SquaredDifference node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_TRUE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Squeeze() - { - op::Squeeze node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Tan() - { - op::Tan node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Tanh() - { - op::Tanh node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_TensorIterator() - { - op::TensorIterator node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Tile() - { - op::v0::Tile node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Unsqueeze() - { - op::v0::Unsqueeze node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - - void op_is_Xor() - { - op::Xor node; - EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_TRUE(op::is_binary_elementwise_logical(&node)); - } -} // namespace - -TEST(op_is, check) -{ - NGRAPH_SUPPRESS_DEPRECATED_START -#define NGRAPH_OP(a, b) op_is_##a(); -#include "opset0_tbl.hpp" -#undef NGRAPH_OP - NGRAPH_SUPPRESS_DEPRECATED_END -} diff --git a/ngraph/test/pass_liveness.cpp b/ngraph/test/pass_liveness.cpp deleted file mode 100644 index 5c3553de381..00000000000 --- a/ngraph/test/pass_liveness.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "ngraph/log.hpp" -#include "ngraph/ngraph.hpp" -#include "ngraph/pass/manager.hpp" -#include "ngraph/pass/visualize_tree.hpp" -#include "pass/liveness.hpp" - -#include "util/test_tools.hpp" - -using namespace std; -using namespace ngraph; -namespace ng = ngraph; - -TEST(liveness, constant) -{ - Shape shape{1}; - auto c = op::Constant::create(element::i32, shape, {5}); - auto f = make_shared(make_shared(c), ParameterVector{}); - - pass::Manager pass_manager; - pass_manager.register_pass(); - pass_manager.run_passes(f); - - auto tmp = f->get_ordered_ops(); - vector> sorted{tmp.begin(), tmp.end()}; - ASSERT_EQ(3, sorted.size()); - EXPECT_EQ(0, sorted[0]->liveness_new_list.size()); - EXPECT_EQ(0, sorted[0]->liveness_free_list.size()); - - // op::Negative is live on output to op::Result - // op::Negative is new - EXPECT_EQ(1, sorted[1]->liveness_new_list.size()); - EXPECT_EQ(0, sorted[1]->liveness_free_list.size()); - - // op::Negative is live on input to op::Result - EXPECT_EQ(0, sorted[2]->liveness_new_list.size()); - // op::Negative is freed - EXPECT_EQ(1, sorted[2]->liveness_free_list.size()); -} diff --git a/ngraph/test/pass_shape_relevance.cpp b/ngraph/test/pass_shape_relevance.cpp deleted file mode 100644 index d288f8d0b52..00000000000 --- a/ngraph/test/pass_shape_relevance.cpp +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "ngraph/ngraph.hpp" -#include "ngraph/pass/manager.hpp" -#include "pass/shape_relevance.hpp" - -NGRAPH_SUPPRESS_DEPRECATED_START - -using namespace ngraph; -using namespace std; - -TEST(shape_relevance, simple) -{ - auto param0 = make_shared(element::f32, Shape{4, 6}); - auto param1 = make_shared(element::f32, Shape{4, 6}); - auto x = make_shared(param0, param1); - - auto f = make_shared(x, ParameterVector{param0, param1}); - - pass::Manager manager; - manager.register_pass(); - manager.run_passes(f); - - ASSERT_FALSE(param0->is_relevant_to_shapes()); - ASSERT_FALSE(param1->is_relevant_to_shapes()); -} - -TEST(shape_relevance, param_direct) -{ - auto param0 = make_shared(element::f32, Shape{4, 6}); - auto param1 = make_shared(element::i64, Shape{4}); - auto x = make_shared(param0, param1, true); - - auto f = make_shared(x, ParameterVector{param0, param1}); - - pass::Manager manager; - manager.register_pass(); - manager.run_passes(f); - - ASSERT_FALSE(param0->is_relevant_to_shapes()); - ASSERT_TRUE(param1->is_relevant_to_shapes()); -} - -TEST(shape_relevance, param_indirect) -{ - auto param0 = make_shared(element::f32, Shape{4, 6}); - auto param1 = make_shared(element::i64, Shape{4}); - auto param2 = make_shared(element::i64, Shape{2}); - - auto c = make_shared(NodeVector{param1, param2}, 0); - auto x = make_shared(param0, c, true); - - auto f = make_shared(x, ParameterVector{param0, param1, param2}); - - pass::Manager manager; - manager.register_pass(); - manager.run_passes(f); - - ASSERT_FALSE(param0->is_relevant_to_shapes()); - ASSERT_TRUE(param1->is_relevant_to_shapes()); - ASSERT_TRUE(param2->is_relevant_to_shapes()); -} - -TEST(shape_relevance, param_shape_of_direct_v0) -{ - auto param0 = make_shared(element::f32, Shape{4, 6}); - - auto x = make_shared(param0, make_shared(param0), true); - - auto f = make_shared(x, ParameterVector{param0}); - - pass::Manager manager; - manager.register_pass(); - manager.run_passes(f); - - ASSERT_FALSE(param0->is_relevant_to_shapes()); -} - -TEST(shape_relevance, param_shape_of_direct_v3) -{ - auto param0 = make_shared(element::f32, Shape{4, 6}); - - auto x = make_shared(param0, make_shared(param0), true); - - auto f = make_shared(x, ParameterVector{param0}); - - pass::Manager manager; - manager.register_pass(); - manager.run_passes(f); - - ASSERT_FALSE(param0->is_relevant_to_shapes()); -} - -TEST(shape_relevance, param_shape_of_direct_i32_v3) -{ - auto param0 = make_shared(element::f32, Shape{4, 6}); - - auto x = make_shared( - param0, make_shared(param0, element::i32), true); - - auto f = make_shared(x, ParameterVector{param0}); - - pass::Manager manager; - manager.register_pass(); - manager.run_passes(f); - - ASSERT_FALSE(param0->is_relevant_to_shapes()); -} - -TEST(shape_relevance, param_shape_of_indirect_v0) -{ - auto param0 = make_shared(element::f32, Shape{4, 6}); - - auto s = make_shared(param0); - auto r = make_shared( - s, op::Constant::create(element::i64, {1}, {0}), op::v1::Reverse::Mode::INDEX); - auto x = make_shared(param0, r, true); - - auto f = make_shared(x, ParameterVector{param0}); - - pass::Manager manager; - manager.register_pass(); - manager.run_passes(f); - - ASSERT_FALSE(param0->is_relevant_to_shapes()); -} - -TEST(shape_relevance, param_shape_of_indirect_v3) -{ - auto param0 = make_shared(element::f32, Shape{4, 6}); - - auto s = make_shared(param0); - auto r = make_shared( - s, op::Constant::create(element::i64, {1}, {0}), op::v1::Reverse::Mode::INDEX); - auto x = make_shared(param0, r, true); - - auto f = make_shared(x, ParameterVector{param0}); - - pass::Manager manager; - manager.register_pass(); - manager.run_passes(f); - - ASSERT_FALSE(param0->is_relevant_to_shapes()); -} - -TEST(shape_relevance, param_shape_of_indirect_i32_v3) -{ - auto param0 = make_shared(element::f32, Shape{4, 6}); - - auto s = make_shared(param0, element::i32); - auto r = make_shared( - s, op::Constant::create(element::i64, {1}, {0}), op::v1::Reverse::Mode::INDEX); - auto x = make_shared(param0, r, true); - - auto f = make_shared(x, ParameterVector{param0}); - - pass::Manager manager; - manager.register_pass(); - manager.run_passes(f); - - ASSERT_FALSE(param0->is_relevant_to_shapes()); -} diff --git a/ngraph/test/provenance.cpp b/ngraph/test/provenance.cpp index c814eb55c1e..f4878341ab7 100644 --- a/ngraph/test/provenance.cpp +++ b/ngraph/test/provenance.cpp @@ -15,7 +15,6 @@ #include "ngraph/ngraph.hpp" #include "ngraph/pass/manager.hpp" #include "ngraph/provenance.hpp" -#include "pass/fused_op_decomposition.hpp" #include "util/provenance_enabler.hpp" using namespace std; @@ -380,61 +379,6 @@ TEST(provenance, builder) } } -TEST(provenance, fused_copy_origin_tags) -{ - test::ProvenanceEnabler provenance_enabler; - - auto p1 = make_shared(element::f32, PartialShape{2, 3, 4}); - p1->add_provenance_tag("P1"); - auto g = make_shared(p1); - g->add_provenance_tag("G"); - auto r = make_shared(g); - auto f = make_shared(ResultVector{r}, ParameterVector{p1}); - - pass::Manager manager; - manager.register_pass(); - manager.run_passes(f); - - traverse_nodes(f, [&](const std::shared_ptr& node) { - auto tags = node->get_provenance_tags(); - if (node == p1) - { - EXPECT_EQ(tags.size(), 1); - EXPECT_TRUE(tags.find("P1") != tags.end()); - } - else if (node == r) - { - } - else - { - EXPECT_TRUE(tags.find("G") != tags.end()); - EXPECT_TRUE(tags.find("") != tags.end()); - } - }); -} - -TEST(provenance, fused_decomposition_tag) -{ - test::ProvenanceEnabler provenance_enabler; - - auto p1 = make_shared(element::f32, PartialShape{2, 3, 4}); - auto fused_op = make_shared(p1); - auto result = make_shared(fused_op); - auto f = make_shared(ResultVector{result}, ParameterVector{p1}); - - pass::Manager manager; - manager.register_pass(); - manager.run_passes(f); - - const auto tag = ""; - auto tag_check = [&tag](std::shared_ptr node) { - auto tags = node->get_provenance_tags(); - EXPECT_TRUE(tags.find(tag) != tags.end()); - }; - const auto decomposed_op = f->get_result()->get_input_node_shared_ptr(0); - traverse_nodes(as_node_vector(decomposed_op->outputs()), tag_check, {p1}); -} - TEST(provenance, empty_group) { auto p1 = make_shared(element::i32, PartialShape{2, 3, 4}); diff --git a/ngraph/test/runtime/CMakeLists.txt b/ngraph/test/runtime/CMakeLists.txt index aa0ddfd6962..d17a37a8b70 100644 --- a/ngraph/test/runtime/CMakeLists.txt +++ b/ngraph/test/runtime/CMakeLists.txt @@ -14,26 +14,8 @@ set (SRC performance_counter.hpp dynamic/dynamic_backend.cpp dynamic/dynamic_backend.hpp - op/avg_pool.cpp - op/avg_pool.hpp - op/convolution.cpp - op/convolution.hpp - op/group_conv.cpp - op/group_conv.hpp pass/dyn_elimination.cpp pass/dyn_elimination.hpp - pass/fused_op_decomposition.cpp - pass/fused_op_decomposition.hpp - pass/implicit_broadcast_elimination.cpp - pass/implicit_broadcast_elimination.hpp - pass/liveness.cpp - pass/liveness.hpp - pass/opset0_downgrade.cpp - pass/opset0_downgrade.hpp - pass/opset1_downgrade.cpp - pass/opset1_downgrade.hpp - pass/opset1_upgrade.cpp - pass/opset1_upgrade.hpp pass/shape_relevance.cpp pass/shape_relevance.hpp ) diff --git a/ngraph/test/runtime/dynamic/dynamic_backend.cpp b/ngraph/test/runtime/dynamic/dynamic_backend.cpp index c7efd915b9e..0ef1f656837 100644 --- a/ngraph/test/runtime/dynamic/dynamic_backend.cpp +++ b/ngraph/test/runtime/dynamic/dynamic_backend.cpp @@ -15,8 +15,6 @@ #include "ngraph/specialize_function.hpp" #include "ngraph/util.hpp" #include "pass/dyn_elimination.hpp" -#include "pass/opset0_downgrade.hpp" -#include "pass/opset1_downgrade.hpp" #include "pass/shape_relevance.hpp" using namespace std; @@ -239,10 +237,8 @@ bool runtime::dynamic::DynamicExecutable::call( pass::Manager passes; // Opset1Downgrade should be moved below DynElimination // when ConstantFolding for v3 ops will be ready - passes.register_pass(); passes.register_pass(); passes.register_pass(); - passes.register_pass(); // Converts dynamic v1 variants to v0 ops passes.set_per_pass_validation(false); // FIXME(amprocte): Vile, temporary hack: we need to do repeated rounds of diff --git a/ngraph/test/runtime/ie/ie_executable.cpp b/ngraph/test/runtime/ie/ie_executable.cpp index 419cd435380..cd31f1e0a7e 100644 --- a/ngraph/test/runtime/ie/ie_executable.cpp +++ b/ngraph/test/runtime/ie/ie_executable.cpp @@ -8,7 +8,6 @@ #include "ngraph/pass/manager.hpp" #include "ngraph/shape.hpp" #include "ngraph/type/element_type.hpp" -#include "pass/opset1_upgrade.hpp" using namespace std; using namespace ngraph; @@ -63,7 +62,7 @@ namespace memcpy(blob_ptr, data, data_size * elem_type.size()); return blob; } -} +} // namespace namespace { @@ -78,21 +77,18 @@ namespace ie_ops.insert(opset4.begin(), opset4.end()); auto& opset5 = get_opset5().get_type_info_set(); ie_ops.insert(opset5.begin(), opset5.end()); - auto& opset6= get_opset6().get_type_info_set(); + auto& opset6 = get_opset6().get_type_info_set(); ie_ops.insert(opset6.begin(), opset6.end()); - auto& opset7= get_opset7().get_type_info_set(); + auto& opset7 = get_opset7().get_type_info_set(); ie_ops.insert(opset7.begin(), opset7.end()); return ie_ops; } -} +} // namespace runtime::ie::IE_Executable::IE_Executable(shared_ptr func, string device) : m_device{device} { static std::set ie_ops = get_ie_ops(); - pass::Manager passes; - passes.register_pass(); - passes.run_passes(func); for (const auto& node : func->get_ops()) { diff --git a/ngraph/test/runtime/interpreter/int_executable.hpp b/ngraph/test/runtime/interpreter/int_executable.hpp index d7edc790aab..8c901cd93c5 100644 --- a/ngraph/test/runtime/interpreter/int_executable.hpp +++ b/ngraph/test/runtime/interpreter/int_executable.hpp @@ -21,7 +21,6 @@ #include "ngraph/runtime/reference/reorg_yolo.hpp" #include "ngraph/runtime/reference/tensor_iterator.hpp" #include "ngraph/runtime/tensor.hpp" -#include "op/avg_pool.hpp" namespace ngraph { diff --git a/ngraph/test/runtime/op/atan2.cpp b/ngraph/test/runtime/op/atan2.cpp deleted file mode 100644 index 4d0af74cba3..00000000000 --- a/ngraph/test/runtime/op/atan2.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "atan2.hpp" -#include "ngraph/op/add.hpp" -#include "ngraph/op/divide.hpp" -#include "ngraph/op/multiply.hpp" -#include "ngraph/op/negative.hpp" -#include "ngraph/op/sqrt.hpp" -#include "ngraph/op/subtract.hpp" - -using namespace std; -using namespace ngraph; - -constexpr NodeTypeInfo op::v0::Atan2::type_info; - -op::v0::Atan2::Atan2(const Output& y, const Output& x, const AutoBroadcastSpec& autob) - : BinaryElementwiseArithmetic(y, x, autob) -{ - constructor_validate_and_infer_types(); -} - -shared_ptr op::v0::Atan2::clone_with_new_inputs(const OutputVector& new_args) const -{ - check_new_args_count(this, new_args); - return make_shared(new_args.at(0), new_args.at(1), this->get_autob()); -} - -bool op::v0::Atan2::visit_attributes(AttributeVisitor& visitor) -{ - BinaryElementwiseArithmetic::visit_attributes(visitor); - return true; -} diff --git a/ngraph/test/runtime/op/atan2.hpp b/ngraph/test/runtime/op/atan2.hpp deleted file mode 100644 index 683edc85162..00000000000 --- a/ngraph/test/runtime/op/atan2.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include - -#include "backend_visibility.hpp" -#include "ngraph/op/util/binary_elementwise_arithmetic.hpp" - -namespace ngraph -{ - namespace op - { - namespace v0 - { - /// \brief Elementwise full arctan operation - class BACKEND_API Atan2 : public util::BinaryElementwiseArithmetic - { - public: - static constexpr NodeTypeInfo type_info{"Atan2", 0}; - const NodeTypeInfo& get_type_info() const override { return type_info; } - Atan2() - : util::BinaryElementwiseArithmetic(AutoBroadcastSpec::NONE) - { - } - - /// \brief atan2(y,x) is the angle from the origin to the point (x,y) (note reversed - /// order). - /// - /// \param y - /// \param x - Atan2(const Output& y, - const Output& x, - const AutoBroadcastSpec& autob = AutoBroadcastSpec()); - std::shared_ptr - clone_with_new_inputs(const OutputVector& new_args) const override; - bool visit_attributes(AttributeVisitor& visitor) override; - }; - } - } -} diff --git a/ngraph/test/runtime/op/avg_pool.cpp b/ngraph/test/runtime/op/avg_pool.cpp deleted file mode 100644 index d8f8d8bb091..00000000000 --- a/ngraph/test/runtime/op/avg_pool.cpp +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "avg_pool.hpp" -#include "ngraph/attribute_visitor.hpp" -#include "ngraph/graph_util.hpp" -#include "ngraph/validation_util.hpp" - -using namespace std; -using namespace ngraph; - -// *** AvgPool OP SET 0 *** -constexpr NodeTypeInfo op::v0::AvgPool::type_info; - -op::v0::AvgPool::AvgPool(const Output& arg, - const Shape& window_shape, - const Strides& window_movement_strides, - const Shape& padding_below, - const Shape& padding_above, - bool include_padding_in_avg_computation, - const PadType& pad_type, - bool ceil_mode) - : Op({arg}) - , m_window_shape(window_shape) - , m_window_movement_strides(window_movement_strides) - , m_padding_below(padding_below) - , m_padding_above(padding_above) - , m_include_padding_in_avg_computation(include_padding_in_avg_computation) - , m_pad_type(pad_type) - , m_ceil_mode(ceil_mode) -{ - constructor_validate_and_infer_types(); -} - -op::v0::AvgPool::AvgPool(const Output& arg, - const Shape& window_shape, - const Strides& window_movement_strides, - const Shape& padding_below, - const Shape& padding_above, - bool include_padding_in_avg_computation, - const PadType& pad_type) - : AvgPool(arg, - window_shape, - window_movement_strides, - padding_below, - padding_above, - include_padding_in_avg_computation, - pad_type, - false) -{ -} - -op::v0::AvgPool::AvgPool(const Output& arg, - const Shape& window_shape, - const Strides& window_movement_strides, - const Shape& padding_below, - const Shape& padding_above, - bool include_padding_in_avg_computation) - : AvgPool(arg, - window_shape, - window_movement_strides, - padding_below, - padding_above, - include_padding_in_avg_computation, - PadType::EXPLICIT) -{ -} - -bool op::v0::AvgPool::visit_attributes(AttributeVisitor& visitor) -{ - visitor.on_attribute("window_shape", m_window_shape); - visitor.on_attribute("window_movement_strides", m_window_movement_strides); - visitor.on_attribute("padding_below", m_padding_below); - visitor.on_attribute("padding_above", m_padding_above); - visitor.on_attribute("include_padding_in_avg_computation", - m_include_padding_in_avg_computation); - visitor.on_attribute("pad_type", m_pad_type); - visitor.on_attribute("ceil_mode", m_ceil_mode); - return true; -} - -void op::v0::AvgPool::validate_and_infer_types() -{ - if (0 == m_window_movement_strides.size()) - { - m_window_movement_strides = Strides(m_window_shape.size(), 1); - } - - if (0 == m_padding_below.size()) - { - m_padding_below = Shape(m_window_shape.size(), 0); - } - - if (0 == m_padding_above.size()) - { - m_padding_above = Shape(m_window_shape.size(), 0); - } - - const PartialShape& arg_shape = get_input_partial_shape(0); - - if (m_pad_type == PadType::SAME_UPPER || m_pad_type == PadType::SAME_LOWER) - { - if (arg_shape.is_static()) - { - CoordinateDiff padding_above, padding_below; - infer_auto_padding(arg_shape.to_shape(), - m_window_shape, - m_window_movement_strides, - Strides(m_window_shape.size(), 1), // No dilation - m_pad_type, - padding_above, - padding_below); - m_padding_above = Shape(padding_above.begin(), padding_above.end()); - m_padding_below = Shape(padding_below.begin(), padding_below.end()); - } - } - - // infer_batched_forward_pooling wants CoordinateDiffs for these, while the pooling ops for - // now still take Shape (no negative padding). - CoordinateDiff padding_below(m_padding_below.begin(), m_padding_below.end()); - CoordinateDiff padding_above(m_padding_above.begin(), m_padding_above.end()); - - set_output_type(0, - get_input_element_type(0), - infer_batched_pooling_forward(this, - arg_shape, - padding_below, - padding_above, - m_window_shape, - m_window_movement_strides, - m_include_padding_in_avg_computation, - m_ceil_mode)); -} - -op::v0::AvgPool::AvgPool(const Output& arg, - const Shape& window_shape, - const Strides& window_movement_strides) - : AvgPool(arg, window_shape, window_movement_strides, Shape(), Shape(), false) -{ -} - -op::v0::AvgPool::AvgPool(const Output& arg, const Shape& window_shape) - : AvgPool(arg, window_shape, Strides(), Shape(), Shape(), false) -{ -} - -const Shape& op::v0::AvgPool::get_window_shape() const -{ - return m_window_shape; -} - -void op::v0::AvgPool::set_window_shape(const Shape& window_shape) -{ - m_window_shape = window_shape; -} - -const Strides& op::v0::AvgPool::get_window_movement_strides() const -{ - return m_window_movement_strides; -} - -void op::v0::AvgPool::set_window_movement_strides(const Strides& window_movement_strides) -{ - m_window_movement_strides = window_movement_strides; -} - -const Shape& op::v0::AvgPool::get_padding_below() const -{ - return m_padding_below; -} - -void op::v0::AvgPool::set_padding_below(const Shape& padding_below) -{ - m_padding_below = padding_below; -} - -const Shape& op::v0::AvgPool::get_padding_above() const -{ - return m_padding_above; -} - -void op::v0::AvgPool::set_padding_above(const Shape& padding_above) -{ - m_padding_above = padding_above; -} - -bool op::v0::AvgPool::get_include_padding_in_avg_computation() const -{ - return m_include_padding_in_avg_computation; -} - -void op::v0::AvgPool::set_include_padding_in_avg_computation( - bool include_padding_in_avg_computation) -{ - m_include_padding_in_avg_computation = include_padding_in_avg_computation; -} - -const op::PadType& op::v0::AvgPool::get_pad_type() const -{ - return m_pad_type; -} - -void op::v0::AvgPool::set_pad_type(const op::PadType& pad_type) -{ - m_pad_type = pad_type; -} - -bool op::v0::AvgPool::get_ceil_mode() const -{ - return m_ceil_mode; -} - -void op::v0::AvgPool::set_ceil_mode(bool ceil_mode) -{ - m_ceil_mode = ceil_mode; -} - -shared_ptr op::v0::AvgPool::clone_with_new_inputs(const OutputVector& new_args) const -{ - check_new_args_count(this, new_args); - return make_shared(new_args.at(0), - m_window_shape, - m_window_movement_strides, - m_padding_below, - m_padding_above, - m_include_padding_in_avg_computation, - m_pad_type, - m_ceil_mode); -} - -shared_ptr op::v0::AvgPool::get_default_value() const -{ - return Constant::create(get_element_type(), get_shape(), {0}); -} diff --git a/ngraph/test/runtime/op/avg_pool.hpp b/ngraph/test/runtime/op/avg_pool.hpp deleted file mode 100644 index 701b3e174f3..00000000000 --- a/ngraph/test/runtime/op/avg_pool.hpp +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include "backend_visibility.hpp" -#include "ngraph/op/op.hpp" -#include "ngraph/op/util/attr_types.hpp" - -namespace ngraph -{ - namespace op - { - namespace v0 - { - /// \brief Batched average pooling operation, with optional padding and window stride. - /// - class BACKEND_API AvgPool : public Op - { - public: - static constexpr NodeTypeInfo type_info{"AvgPool", 0}; - const NodeTypeInfo& get_type_info() const override { return type_info; } - /// \brief Constructs a batched average pooling operation. - AvgPool() = default; - - /// \brief Constructs a batched average pooling operation. - /// - /// \param arg The output producing the input data batch tensor.
- /// `[d1, dn]` - /// \param window_shape The window shape.
- /// `[n]` - /// \param window_movement_strides The window movement strides.
- /// `[n]` - /// \param padding_below The below-padding shape.
- /// `[n]` - /// \param padding_above The above-padding shape.
- /// `[n]` - /// \param include_padding_in_avg_computation If true then averages include padding - /// elements, each treated as the number zero. If false, padding elements are - /// entirely ignored when computing averages. \param pad_type Padding type to use - /// for additional padded dimensions \param ceil_mode Whether to use ceiling while - /// computing output shape. - AvgPool(const Output& arg, - const Shape& window_shape, - const Strides& window_movement_strides, - const Shape& padding_below, - const Shape& padding_above, - bool include_padding_in_avg_computation, - const PadType& pad_type, - bool ceil_mode); - - /// \brief Constructs a batched average pooling operation. - /// - /// \param arg The output producing the input data batch tensor.
- /// `[d1, dn]` - /// \param window_shape The window shape.
- /// `[n]` - /// \param window_movement_strides The window movement strides.
- /// `[n]` - /// \param padding_below The below-padding shape.
- /// `[n]` - /// \param padding_above The above-padding shape.
- /// `[n]` - /// \param include_padding_in_avg_computation If true then averages include padding - /// elements, each treated as the number zero. If false, padding elements are - /// entirely ignored when computing averages. \param pad_type Padding type to use - /// for additional padded dimensions - AvgPool(const Output& arg, - const Shape& window_shape, - const Strides& window_movement_strides, - const Shape& padding_below, - const Shape& padding_above, - bool include_padding_in_avg_computation, - const PadType& pad_type); - - /// \brief Constructs a batched average pooling operation. - /// - /// \param arg The output producing the input data batch tensor.
- /// `[d1, dn]` - /// \param window_shape The window shape.
- /// `[n]` - /// \param window_movement_strides The window movement strides.
- /// `[n]` - /// \param padding_below The below-padding shape.
- /// `[n]` - /// \param padding_above The above-padding shape.
- /// `[n]` - /// \param include_padding_in_avg_computation If true then averages include padding - /// elements, each treated as the number zero. If false, padding elements are - /// entirely ignored when computing averages. - AvgPool(const Output& arg, - const Shape& window_shape, - const Strides& window_movement_strides, - const Shape& padding_below, - const Shape& padding_above, - bool include_padding_in_avg_computation = false); - - /// \brief Constructs a batched, unpadded average pooling operation (i.e., all - /// padding shapes are set to 0). - /// - /// \param arg The output producing the input data batch tensor.
- /// `[d1, ..., dn]` - /// \param window_shape The window shape.
- /// `[n]` - /// \param window_movement_strides The window movement strides.
- /// `[n]` - AvgPool(const Output& arg, - const Shape& window_shape, - const Strides& window_movement_strides); - - /// \brief Constructs an unstrided batched convolution operation (i.e., all window - /// movement strides are 1 and all padding shapes are set to 0). - /// - /// \param arg The output producing the input data batch tensor.
- /// `[d1, ..., dn]` - /// \param window_shape The window shape.
- /// `[n]` - AvgPool(const Output& arg, const Shape& window_shape); - - bool visit_attributes(AttributeVisitor& visitor) override; - - void validate_and_infer_types() override; - - virtual std::shared_ptr - clone_with_new_inputs(const OutputVector& new_args) const override; - - /// \return The window shape. - const Shape& get_window_shape() const; - void set_window_shape(const Shape& window_shape); - /// \return The window movement strides. - const Strides& get_window_movement_strides() const; - void set_window_movement_strides(const Strides& window_movement_strides); - /// \return The below-padding shape. - const Shape& get_padding_below() const; - void set_padding_below(const Shape& padding_below); - /// \return The above-padding shape. - const Shape& get_padding_above() const; - void set_padding_above(const Shape& padding_above); - bool get_include_padding_in_avg_computation() const; - void - set_include_padding_in_avg_computation(bool include_padding_in_avg_computation); - /// \return The pad type for pooling. - const PadType& get_pad_type() const; - void set_pad_type(const PadType& pad_type); - bool get_ceil_mode() const; - void set_ceil_mode(bool ceil_mode); - /// \return The default value for AvgPool. - NGRAPH_SUPPRESS_DEPRECATED_START - virtual std::shared_ptr get_default_value() const override; - NGRAPH_SUPPRESS_DEPRECATED_END - - protected: - Shape m_window_shape; - Strides m_window_movement_strides; - Shape m_padding_below; - Shape m_padding_above; - bool m_include_padding_in_avg_computation{false}; - PadType m_pad_type{PadType::EXPLICIT}; - bool m_ceil_mode{false}; - }; - } // namespace v0 - } // namespace op -} // namespace ngraph diff --git a/ngraph/test/runtime/op/convolution.cpp b/ngraph/test/runtime/op/convolution.cpp deleted file mode 100644 index 1d4d8bea6c6..00000000000 --- a/ngraph/test/runtime/op/convolution.cpp +++ /dev/null @@ -1,343 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "convolution.hpp" -#include "ngraph/axis_vector.hpp" -#include "ngraph/coordinate_diff.hpp" -#include "ngraph/op/reshape.hpp" -#include "ngraph/util.hpp" -#include "ngraph/validation_util.hpp" - -using namespace std; -using namespace ngraph; - -// *** Convolution OP SET 0 *** -constexpr NodeTypeInfo op::v0::Convolution::type_info; - -op::v0::Convolution::Convolution(const Output& data_batch, - const Output& filters, - const Strides& window_movement_strides, - const Strides& window_dilation_strides, - const CoordinateDiff& padding_below, - const CoordinateDiff& padding_above, - const Strides& data_dilation_strides, - const PadType& pad_type) - : Op({data_batch, filters}) - , m_window_movement_strides(window_movement_strides) - , m_window_dilation_strides(window_dilation_strides) - , m_padding_below(padding_below) - , m_padding_above(padding_above) - , m_data_dilation_strides(data_dilation_strides) - , m_pad_type(pad_type) -{ - constructor_validate_and_infer_types(); -} - -bool op::v0::Convolution::visit_attributes(AttributeVisitor& visitor) -{ - visitor.on_attribute("window_movement_strides", m_window_movement_strides); - visitor.on_attribute("window_dilation_strides", m_window_dilation_strides); - visitor.on_attribute("data_dilation_strides", m_data_dilation_strides); - visitor.on_attribute("padding_below", m_padding_below); - visitor.on_attribute("padding_above", m_padding_above); - visitor.on_attribute("pad_type", m_pad_type); - return true; -} - -void op::v0::Convolution::validate_and_infer_types() -{ - const PartialShape& data_batch_shape = get_input_partial_shape(0); - element::Type data_batch_et = get_input_element_type(0); - const PartialShape& filters_shape = get_input_partial_shape(1); - element::Type filters_et = get_input_element_type(1); - - if (m_data_dilation_strides.size() == 0) - { - m_data_dilation_strides = conv_default_strides(this, data_batch_shape, filters_shape); - } - - if (m_window_movement_strides.size() == 0) - { - m_window_movement_strides = conv_default_strides(this, data_batch_shape, filters_shape); - } - - if (m_window_dilation_strides.size() == 0) - { - m_window_dilation_strides = conv_default_strides(this, data_batch_shape, filters_shape); - } - - if (m_padding_below.size() == 0) - { - m_padding_below = conv_default_padding(this, data_batch_shape, filters_shape); - } - - if (m_padding_above.size() == 0) - { - m_padding_above = conv_default_padding(this, data_batch_shape, filters_shape); - } - - if (m_pad_type == PadType::SAME_UPPER || m_pad_type == PadType::SAME_LOWER) - { - if (data_batch_shape.is_static() && filters_shape.is_static()) - { - // TODO: data dilation - m_padding_below.clear(); - m_padding_above.clear(); - auto filter_shape = filters_shape.to_shape(); - filter_shape.erase(filter_shape.begin(), filter_shape.begin() + 2); // Remove {O,I} - infer_auto_padding(data_batch_shape.to_shape(), - filter_shape, - m_window_movement_strides, - m_window_dilation_strides, - m_pad_type, - m_padding_above, - m_padding_below); - } - } - - element::Type result_et; - PartialShape result_shape; - - NODE_VALIDATION_CHECK( - this, - element::Type::merge(result_et, data_batch_et, filters_et), - "Element types for data batch and filters do not match (data batch element type: ", - data_batch_et, - ", filters element type: ", - filters_et, - ")."); - - result_shape = infer_convolution_forward(this, - data_batch_shape, - m_data_dilation_strides, - m_padding_below, - m_padding_above, - filters_shape, - m_window_movement_strides, - m_window_dilation_strides); - - set_output_type(0, result_et, result_shape); -} - -op::v0::Convolution::Convolution(const Output& data_batch, - const Output& filters, - const Strides& window_movement_strides, - const Strides& window_dilation_strides, - const CoordinateDiff& padding_below, - const CoordinateDiff& padding_above) - : Convolution(data_batch, - filters, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - Strides()) -{ -} - -op::v0::Convolution::Convolution(const Output& data_batch, - const Output& filters, - const Strides& window_movement_strides, - const Strides& window_dilation_strides) - : Convolution(data_batch, - filters, - window_movement_strides, - window_dilation_strides, - CoordinateDiff(), - CoordinateDiff()) -{ -} - -op::v0::Convolution::Convolution(const Output& data_batch, - const Output& filters, - const Strides& window_movement_strides) - : Convolution(data_batch, - filters, - window_movement_strides, - Strides(), - CoordinateDiff(), - CoordinateDiff()) -{ -} - -op::v0::Convolution::Convolution(const Output& data_batch, const Output& filters) - : Convolution(data_batch, filters, Strides(), Strides(), CoordinateDiff(), CoordinateDiff()) -{ -} - -shared_ptr op::v0::Convolution::clone_with_new_inputs(const OutputVector& new_args) const -{ - check_new_args_count(this, new_args); - return make_shared(new_args.at(0), - new_args.at(1), - m_window_movement_strides, - m_window_dilation_strides, - m_padding_below, - m_padding_above, - m_data_dilation_strides, - m_pad_type); -} - -constexpr NodeTypeInfo op::v0::ConvolutionBackpropData::type_info; -shared_ptr op::v0::Convolution::get_default_value() const -{ - return ngraph::make_constant_from_string("0", get_element_type(), get_shape()); -} - -op::v0::ConvolutionBackpropData::ConvolutionBackpropData( - const Shape& data_batch_shape, - const Output& filters, - const Output& output_delta, - const Strides& window_movement_strides_forward, - const Strides& window_dilation_strides_forward, - const CoordinateDiff& padding_below_forward, - const CoordinateDiff& padding_above_forward, - const Strides& data_dilation_strides_forward) - : Op({filters, output_delta}) - , m_data_batch_shape(data_batch_shape) - , m_window_movement_strides_forward(window_movement_strides_forward) - , m_window_dilation_strides_forward(window_dilation_strides_forward) - , m_padding_below_forward(padding_below_forward) - , m_padding_above_forward(padding_above_forward) - , m_data_dilation_strides_forward(data_dilation_strides_forward) -{ - constructor_validate_and_infer_types(); -} - -bool op::v0::ConvolutionBackpropData::visit_attributes(AttributeVisitor& visitor) -{ - visitor.on_attribute("data_batch_shape", m_data_batch_shape); - visitor.on_attribute("window_movement_strides_forward", m_window_movement_strides_forward); - visitor.on_attribute("window_dilation_strides_forward", m_window_dilation_strides_forward); - visitor.on_attribute("padding_below_forward", m_padding_below_forward); - visitor.on_attribute("padding_above_forward", m_padding_above_forward); - visitor.on_attribute("data_dilation_strides_forward", m_data_dilation_strides_forward); - return true; -} - -void op::v0::ConvolutionBackpropData::validate_and_infer_types() -{ - // Backprop to data is itself convolution, with inputs/outputs/attributes transmogrified as - // follows. - // - // Forward Backward - // "N" axis for data batch 0 0 - // "C" axis for data batch 1 1 - // "Co" axis for filters 0 0 - // "Ci" axis for filters 1 1 - // "N" axis for output 0 0 - // "C" axis for output 1 1 - // Data batch x delta - // Data batch shape S_x S_o - // Filters f reverse(f) [on spatial axes] - // Filters shape S_f S_f - // Window movement strides q_x p_x - // Window dilation strides p_f p_f - // Padding below a_x (S_f - 1)p_f - a_x - // Padding above b_x (S_f - 1)p_f + - // + ((a_x + (S_x - 1)p_x + b_x - (S_f - 1)p_f) - // % q_x) - // - b_x - // Data dilation strides p_x q_x - // Output shape S_o S_x - // - // To _validate_, we simply need to check/infer the output shape of the forward convolution, - // then check to make sure that the incoming delta has the same shape as the forward output. - const PartialShape& filters_shape = get_input_partial_shape(0); - element::Type filters_et = get_input_element_type(0); - const PartialShape& delta_shape = get_input_partial_shape(1); - element::Type delta_et = get_input_element_type(1); - - element::Type forward_result_et; - PartialShape forward_result_shape; - - NODE_VALIDATION_CHECK( - this, - element::Type::merge(forward_result_et, delta_et, filters_et), - "Element types for data batch and filters do not match (data batch element type: ", - delta_et, - ", filters element type: ", - filters_et, - ")."); - - forward_result_shape = infer_convolution_forward(this, - m_data_batch_shape, - m_data_dilation_strides_forward, - m_padding_below_forward, - m_padding_above_forward, - filters_shape, - m_window_movement_strides_forward, - m_window_dilation_strides_forward); - - NODE_VALIDATION_CHECK(this, - forward_result_shape.compatible(delta_shape), - "Inferred forward output shape (", - forward_result_shape, - ") does not match shape of ", - "delta (", - delta_shape, - ")."); - - set_output_type(0, forward_result_et, m_data_batch_shape); -} - -shared_ptr - op::v0::ConvolutionBackpropData::clone_with_new_inputs(const OutputVector& new_args) const -{ - check_new_args_count(this, new_args); - return make_shared(m_data_batch_shape, - new_args.at(0), - new_args.at(1), - m_window_movement_strides_forward, - m_window_dilation_strides_forward, - m_padding_below_forward, - m_padding_above_forward, - m_data_dilation_strides_forward); -} - -CoordinateDiff op::v0::ConvolutionBackpropData::compute_backward_delta_out_pad_below() const -{ - auto& in_shape = get_data_batch_shape(); - auto& filter_dilation = get_window_dilation_strides_forward(); - auto& filter_shape = get_input_shape(0); - auto& in_pad_below = get_padding_below_forward(); - size_t spatial_dim_count = static_cast(in_shape.size()) - 2; - - CoordinateDiff backward_delta_out_pad_below; - backward_delta_out_pad_below.resize(spatial_dim_count); - - for (size_t i = 0; i < spatial_dim_count; i++) - { - backward_delta_out_pad_below[i] = - (static_cast(filter_shape[i + 2]) - 1) * filter_dilation[i] - - in_pad_below[i]; - } - return backward_delta_out_pad_below; -} - -CoordinateDiff op::v0::ConvolutionBackpropData::compute_backward_delta_out_pad_above() const -{ - auto& in_shape = get_data_batch_shape(); - auto& filter_dilation = get_window_dilation_strides_forward(); - auto& filter_shape = get_input_shape(0); - auto& in_pad_below = get_padding_below_forward(); - auto& in_pad_above = get_padding_above_forward(); - auto& in_dilation = get_data_dilation_strides_forward(); - auto& stride = get_window_movement_strides_forward(); - size_t spatial_dim_count = static_cast(in_shape.size()) - 2; - - CoordinateDiff backward_delta_out_pad_above; - backward_delta_out_pad_above.resize(spatial_dim_count); - - for (size_t i = 0; i < spatial_dim_count; i++) - { - backward_delta_out_pad_above[i] = - (static_cast(filter_shape[i + 2]) - 1) * filter_dilation[i] + - ((in_pad_below[i] + ((in_shape[i + 2]) - 1) * in_dilation[i] + in_pad_above[i] - - (static_cast(filter_shape[i + 2]) - 1) * filter_dilation[i]) % - stride[i]) - - in_pad_above[i]; - } - return backward_delta_out_pad_above; -} diff --git a/ngraph/test/runtime/op/convolution.hpp b/ngraph/test/runtime/op/convolution.hpp deleted file mode 100644 index f5d45d26918..00000000000 --- a/ngraph/test/runtime/op/convolution.hpp +++ /dev/null @@ -1,304 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include "backend_visibility.hpp" -#include "ngraph/coordinate_diff.hpp" -#include "ngraph/op/op.hpp" -#include "ngraph/op/util/attr_types.hpp" - -namespace ngraph -{ - namespace op - { - namespace v0 - { - /// \brief Batched convolution operation, with optional window dilation and stride. - /// - class BACKEND_API Convolution : public Op - { - public: - static constexpr NodeTypeInfo type_info{"Convolution", 0}; - const NodeTypeInfo& get_type_info() const override { return type_info; } - /// \brief Constructs a batched convolution operation. - Convolution() = default; - /// \brief Constructs a batched convolution operation. - /// - /// \param data_batch The node producing the input data batch tensor.
- /// `[N, C_IN, D1, ... Df]` - /// \param filters The node producing the filters tensor.
- /// `[C_OUT, C_IN, F1, ... Ff]` - /// \param window_movement_strides The window movement strides.
- /// `[f]` - /// \param window_dilation_strides The window dilation strides.
- /// `[f]` - /// \param padding_below The padding-below sizes.
- /// `[f]` - /// \param padding_above The padding-above sizes.
- /// `[f]` - /// \param data_dilation_strides The data dilation strides.
- /// `[f]` - /// \param pad_type The pad type for automatically computing padding sizes.
- /// `[f]` - /// - /// Output `[N, C_OUT, R1, ... Rf]` - /// - Convolution(const Output& data_batch, - const Output& filters, - const Strides& window_movement_strides, - const Strides& window_dilation_strides, - const CoordinateDiff& padding_below, - const CoordinateDiff& padding_above, - const Strides& data_dilation_strides, - const PadType& pad_type = PadType::EXPLICIT); - - /// \brief Constructs a batched convolution operation with no data dilation (i.e., - /// all - /// data dilation strides are 1). - /// ngraph/test/runtime/interpreter/unit_test.manifest - /// \param data_batch The node producing the input data batch tensor.
- /// `[N, C_IN, D1, ... Df]` - /// \param filters The node producing the filters tensor.
- /// `[C_OUT, C_IN, F1, ... Ff]` - /// \param window_movement_strides The window movement strides.
- /// `[f]` - /// \param window_dilation_strides The window dilation strides.
- /// `[f]` - /// \param padding_below The padding-below sizes.
- /// `[f]` - /// \param padding_above The padding-above sizes.
- /// `[f]` - /// - /// Output `[N, C_OUT, R1, ... Rf]` - /// - Convolution(const Output& data_batch, - const Output& filters, - const Strides& window_movement_strides, - const Strides& window_dilation_strides, - const CoordinateDiff& padding_below, - const CoordinateDiff& padding_above); - - /// \brief Constructs a batched convolution operation with no padding or data - /// dilation - /// (i.e., padding above and below are 0 everywhere, and all data dilation - /// strides are 1). - /// - /// \param data_batch The node producing the input data batch tensor.
- /// `[N, C_IN, D1, ... Df]` - /// \param filters The node producing the filters tensor.
- /// `[C_OUT, C_IN, F1, ... Ff]` - /// \param window_movement_strides The window movement strides.
- /// `[f]` - /// \param window_dilation_strides The window dilation strides.
- /// `[f]` - /// - /// Output `[N, C_OUT, R1, ... Rf]` - /// - Convolution(const Output& data_batch, - const Output& filters, - const Strides& window_movement_strides, - const Strides& window_dilation_strides); - - /// \brief Constructs a batched convolution operation with no window dilation, - /// padding, - /// or data dilation (i.e., padding above and below are 0 everywhere, and all - /// window/data dilation strides are 1). - /// - /// \param data_batch The node producing the input data batch tensor.
- /// `[N, C_IN, D1, ... Df]` - /// \param filters The node producing the filters tensor.
- /// `[C_OUT, C_IN, F1, ... Ff]` - /// \param window_movement_strides The window movement strides.
- /// `[f]` - /// - /// Output `[N, C_OUT, R1, ... Rf]` - /// - Convolution(const Output& data_batch, - const Output& filters, - const Strides& window_movement_strides); - - /// \brief Constructs a batched convolution operation with no window dilation or - /// movement stride (i.e., padding above and below are 0 everywhere, and all - /// window/data dilation strides and window movement strides are 1). - /// - /// \param data_batch The node producing the input data batch tensor.
- /// `[N, C_IN, D1, ... Df]` - /// \param filters The node producing the filters tensor.
- /// `[C_OUT, C_IN, F1, ... Ff]` - /// - /// Output `[N, C_OUT, R1, ... Rf]` - /// - Convolution(const Output& data_batch, const Output& filters); - - void validate_and_infer_types() override; - bool visit_attributes(AttributeVisitor& visitor) override; - - virtual std::shared_ptr - clone_with_new_inputs(const OutputVector& new_args) const override; - - /// \return The window movement strides. - const Strides& get_window_movement_strides() const - { - return m_window_movement_strides; - } - void set_window_movement_strides(const Strides& window_movement_strides) - { - m_window_movement_strides = window_movement_strides; - } - /// \return The window dilation strides. - const Strides& get_window_dilation_strides() const - { - return m_window_dilation_strides; - } - void set_window_dilation_strides(const Strides& window_dilation_strides) - { - m_window_dilation_strides = window_dilation_strides; - } - /// \return The padding-below sizes (possibly negative). - const CoordinateDiff& get_padding_below() const { return m_padding_below; } - void set_padding_below(const CoordinateDiff& padding_below) - { - m_padding_below = padding_below; - } - /// \return The padding-above sizes (possibly negative). - const CoordinateDiff& get_padding_above() const { return m_padding_above; } - void set_adding_above(const CoordinateDiff& padding_above) - { - m_padding_above = padding_above; - } - /// \return The input data dilation strides. - const Strides& get_data_dilation_strides() const { return m_data_dilation_strides; } - void set_data_dilation_strides(const Strides& data_dilation_strides) - { - m_data_dilation_strides = data_dilation_strides; - } - /// \return The pad type for convolution. - const PadType& get_pad_type() const { return m_pad_type; } - void set_pad_type(const PadType& pad_type) { m_pad_type = pad_type; } - /// \return The default value for Convolution. - NGRAPH_SUPPRESS_DEPRECATED_START - virtual std::shared_ptr get_default_value() const override; - NGRAPH_SUPPRESS_DEPRECATED_END - - protected: - Strides m_window_movement_strides; - Strides m_window_dilation_strides; - CoordinateDiff m_padding_below; - CoordinateDiff m_padding_above; - Strides m_data_dilation_strides; - PadType m_pad_type; - }; - - /// \brief Data batch backprop for batched convolution operation. - class BACKEND_API ConvolutionBackpropData : public Op - { - public: - static constexpr NodeTypeInfo type_info{"ConvolutionBackpropData", 0}; - const NodeTypeInfo& get_type_info() const override { return type_info; } - /// \brief Constructs a batched-convolution data batch-backprop operation. - ConvolutionBackpropData() = default; - /// - /// \brief Constructs a batched-convolution data batch-backprop operation. - /// - /// \param data_batch_shape The shape of the data batch from - /// forward-prop. - /// \param filters The node producing the filters from - /// forward-prop. - /// \param data The node producing output delta. - /// \param window_movement_strides_forward The window movement strides from - /// forward-prop. - /// \param window_dilation_strides_forward The window dilation strides from - /// forward-prop. - /// \param padding_below_forward The padding-below sizes from - /// forward-prop. - /// \param padding_above_forward The padding-above sizes from - /// forward-prop. - /// \param data_dilation_strides_forward The data dilation strides from - /// forward-prop. - /// - ConvolutionBackpropData(const Shape& data_batch_shape, - const Output& filters, - const Output& data, - const Strides& window_movement_strides_forward, - const Strides& window_dilation_strides_forward, - const CoordinateDiff& padding_below_forward, - const CoordinateDiff& padding_above_forward, - const Strides& data_dilation_strides_forward); - - void validate_and_infer_types() override; - bool visit_attributes(AttributeVisitor& visitor) override; - - virtual std::shared_ptr - clone_with_new_inputs(const OutputVector& new_args) const override; - - /// \return The data batch shape. - const Shape& get_data_batch_shape() const { return m_data_batch_shape; } - void set_data_batch_shape(const Shape& data_batch_shape) - { - m_data_batch_shape = data_batch_shape; - } - /// \return The window movement strides from the forward prop. - const Strides& get_window_movement_strides_forward() const - { - return m_window_movement_strides_forward; - } - void set_window_movement_strides_forward( - const Strides& window_movement_strides_forward) - { - m_window_movement_strides_forward = window_movement_strides_forward; - } - /// \return The window dilation strides from the forward prop. - const Strides& get_window_dilation_strides_forward() const - { - return m_window_dilation_strides_forward; - } - void set_window_dilation_strides_forward( - const Strides& window_dilation_strides_forward) - { - m_window_dilation_strides_forward = window_dilation_strides_forward; - } - /// \return The padding-below sizes (possibly negative) from the forward prop. - const CoordinateDiff& get_padding_below_forward() const - { - return m_padding_below_forward; - } - void set_padding_below_forward(const CoordinateDiff& padding_below_forward) - { - m_padding_below_forward = padding_below_forward; - } - /// \return The padding-above sizes (possibly negative) from the forward prop. - const CoordinateDiff& get_padding_above_forward() const - { - return m_padding_above_forward; - } - void set_padding_above_forward(const CoordinateDiff& padding_above_forward) - { - m_padding_above_forward = padding_above_forward; - } - /// \return The input data dilation strides from the forward prop. - const Strides& get_data_dilation_strides_forward() const - { - return m_data_dilation_strides_forward; - } - void set_data_dilation_strides_forward(const Strides& data_dilation_strides_forward) - { - m_data_dilation_strides_forward = data_dilation_strides_forward; - } - - // Compute the pad_above values to be used if in a convolution - CoordinateDiff compute_backward_delta_out_pad_above() const; - CoordinateDiff compute_backward_delta_out_pad_below() const; - - protected: - Shape m_data_batch_shape; - Strides m_window_movement_strides_forward; - Strides m_window_dilation_strides_forward; - CoordinateDiff m_padding_below_forward; - CoordinateDiff m_padding_above_forward; - Strides m_data_dilation_strides_forward; - }; - } // namespace v0 - } // namespace op -} // namespace ngraph diff --git a/ngraph/test/runtime/op/group_conv.cpp b/ngraph/test/runtime/op/group_conv.cpp deleted file mode 100644 index 1a9ce2b464a..00000000000 --- a/ngraph/test/runtime/op/group_conv.cpp +++ /dev/null @@ -1,319 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include "convolution.hpp" -#include "group_conv.hpp" -#include "ngraph/attribute_visitor.hpp" -#include "ngraph/builder/reshape.hpp" -#include "ngraph/builder/split.hpp" -#include "ngraph/op/concat.hpp" -#include "ngraph/op/convolution.hpp" -#include "ngraph/validation_util.hpp" - -using namespace std; -using namespace ngraph; - -NGRAPH_SUPPRESS_DEPRECATED_START - -//------------------------------------------------------------------------------ -// v0::GroupConvolution -//------------------------------------------------------------------------------ - -constexpr NodeTypeInfo op::v0::GroupConvolution::type_info; - -op::v0::GroupConvolution::GroupConvolution(const Output& data_batch, - const Output& filters, - const Strides& window_movement_strides, - const Strides& window_dilation_strides, - const CoordinateDiff& padding_below, - const CoordinateDiff& padding_above, - const Strides& data_dilation_strides, - const size_t groups, - const PadType& pad_type) - : FusedOp({data_batch, filters}) - , m_window_movement_strides(window_movement_strides) - , m_window_dilation_strides(window_dilation_strides) - , m_padding_below(padding_below) - , m_padding_above(padding_above) - , m_data_dilation_strides(data_dilation_strides) - , m_groups(groups) - , m_pad_type(pad_type) - , m_groups_in_filters(false) -{ - constructor_validate_and_infer_types(); -} - -op::v0::GroupConvolution::GroupConvolution(const Output& data_batch, - const Output& filters, - const Strides& window_movement_strides, - const Strides& window_dilation_strides, - const CoordinateDiff& padding_below, - const CoordinateDiff& padding_above, - const Strides& data_dilation_strides, - const PadType& pad_type) - : FusedOp({data_batch, filters}) - , m_window_movement_strides(window_movement_strides) - , m_window_dilation_strides(window_dilation_strides) - , m_padding_below(padding_below) - , m_padding_above(padding_above) - , m_data_dilation_strides(data_dilation_strides) - , m_groups(0) - , m_pad_type(pad_type) - , m_groups_in_filters(true) -{ - constructor_validate_and_infer_types(); -} - -void op::v0::GroupConvolution::pre_validate_and_infer_types() -{ - auto data_shape = get_input_partial_shape(0); - auto filters_shape = get_input_partial_shape(1); - - if (data_shape.is_static() && filters_shape.is_static()) - { - // Update groups - if (m_groups_in_filters) - { - m_groups = get_input_partial_shape(1)[0].get_length(); - } - - // Data channels - NODE_VALIDATION_CHECK(this, - data_shape.to_shape()[1] % get_groups() == 0, - "Data channels not a multiple of group size"); - // Output channels - NODE_VALIDATION_CHECK(this, - filters_shape.to_shape()[0] % get_groups() == 0, - "# Filters not a multiple of group size"); - - // Input Filters - NODE_VALIDATION_CHECK(this, - (filters_shape.to_shape()[m_groups_in_filters ? 2 : 1] * - get_groups()) == data_shape.to_shape()[1], - "Incorrect number of channels per filter"); - } - else - { - set_output_type(0, get_input_element_type(0), PartialShape::dynamic()); - } -} - -void op::v0::GroupConvolution::post_validate_and_infer_types() -{ - auto data_shape = get_input_partial_shape(0); - auto filters_shape = get_input_partial_shape(1); - if (data_shape.is_static() && filters_shape.is_static()) - { - if (m_pad_type == PadType::SAME_UPPER || m_pad_type == PadType::SAME_LOWER) - { - m_padding_below.clear(); - m_padding_above.clear(); - auto filter_shape = filters_shape.to_shape(); - filter_shape.erase(filter_shape.begin(), filter_shape.begin() + 2); // Remove {O,I} - infer_auto_padding(data_shape.to_shape(), - filter_shape, - m_window_movement_strides, - m_window_dilation_strides, - m_pad_type, - m_padding_above, - m_padding_below); - } - } -} - -Shape op::v0::GroupConvolution::get_weights_dimensions() const -{ - auto data_shape = get_input_shape(0); - auto weights_shape = get_input_shape(1); - // check if weights already includes groups - if (m_groups_in_filters) - { - return weights_shape; - } - // reshape weights into 5d tensors that includes groups - const size_t OC = 0; - const size_t OC_IN_OUTPUT = 1; - const size_t IC = 1; - Shape weights_shape_groups{weights_shape}; - // adjust output and channel given a number of groups - - weights_shape_groups.at(OC) = get_shape().at(OC_IN_OUTPUT) / get_groups(); - weights_shape_groups.at(IC) = data_shape.at(IC) / get_groups(); - // push_front the number of groups - weights_shape_groups.insert(weights_shape_groups.begin(), get_groups()); - return weights_shape_groups; -} - -shared_ptr op::v0::GroupConvolution::clone_with_new_inputs(const OutputVector& new_args) const -{ - check_new_args_count(this, new_args); - - if (m_groups_in_filters) - { - return make_shared(new_args.at(0), - new_args.at(1), - get_window_movement_strides(), - get_window_dilation_strides(), - get_padding_below(), - get_padding_above(), - get_data_dilation_strides(), - get_pad_type()); - } - else - { - return make_shared(new_args.at(0), - new_args.at(1), - get_window_movement_strides(), - get_window_dilation_strides(), - get_padding_below(), - get_padding_above(), - get_data_dilation_strides(), - get_groups(), - get_pad_type()); - } -} - -OutputVector op::v0::GroupConvolution::decompose_op() const -{ - auto data = input_value(0); - auto filters = input_value(1); - auto filters_shape = get_input_shape(1); - // Split one convolution op to N ops where N is the number of groups - // and concat results after computation. - NodeVector convolution_nodes; - - // slice data - auto sliced_data = builder::opset1::split(data, get_groups(), 1); - // slice filters - auto sliced_filters = builder::opset1::split(filters, get_groups(), 0); - auto shape = Shape(std::next(std::begin(filters_shape), 1), std::end(filters_shape)); - for (std::size_t group{0}; group < get_groups(); ++group) - { - auto sliced_filter = sliced_filters[group]; - if (m_groups_in_filters) - { - // Remove group dimension after slicing - sliced_filter = builder::opset1::reshape(sliced_filters[group], shape); - } - convolution_nodes.push_back( - std::make_shared(sliced_data[group], - sliced_filter, - m_window_movement_strides, - m_window_dilation_strides, - m_padding_below, - m_padding_above, - m_data_dilation_strides, - m_pad_type)); - } - std::size_t concatenation_axis = 1; - return {std::make_shared(convolution_nodes, concatenation_axis)}; -} - -//------------------------------------------------------------------------------ -// v0::GroupConvolutionBackpropData -//------------------------------------------------------------------------------ - -constexpr NodeTypeInfo op::v0::GroupConvolutionBackpropData::type_info; - -op::v0::GroupConvolutionBackpropData::GroupConvolutionBackpropData( - const Output& data_batch, - const Output& filters, - const Output& output_delta, - const Strides& window_movement_strides, - const Strides& window_dilation_strides, - const CoordinateDiff& padding_below, - const CoordinateDiff& padding_above, - const size_t groups) - : FusedOp({data_batch, filters, output_delta}) - , m_window_movement_strides(window_movement_strides) - , m_window_dilation_strides(window_dilation_strides) - , m_padding_below(padding_below) - , m_padding_above(padding_above) - , m_groups(groups) -{ - constructor_validate_and_infer_types(); -} - -void op::v0::GroupConvolutionBackpropData::pre_validate_and_infer_types() -{ - element::Type data_element_type = get_input_element_type(2); - element::Type filters_elem_type = get_input_element_type(1); - - NODE_VALIDATION_CHECK(this, - data_element_type.is_dynamic() || data_element_type.is_real(), - "Output delta element type must be f16, bf16, f32, f64 or dynamic (got ", - data_element_type, - ")."); - NODE_VALIDATION_CHECK(this, - filters_elem_type.is_dynamic() || filters_elem_type.is_real(), - "Filters element type must be f16, bf16, f32, f64 or dynamic (got ", - filters_elem_type, - ")."); - - PartialShape data_pshape = get_input_partial_shape(0); - PartialShape filters_pshape = get_input_partial_shape(1); - PartialShape delta_pshape = get_input_partial_shape(2); - - if (data_pshape.is_dynamic() || filters_pshape.is_dynamic() || delta_pshape.is_dynamic()) - { - set_output_type(0, data_element_type, PartialShape::dynamic()); - } -} - -shared_ptr - op::v0::GroupConvolutionBackpropData::clone_with_new_inputs(const OutputVector& new_args) const -{ - if (new_args.size() != 3) - { - throw ngraph_error("Incorrect number of new arguments"); - } - - return make_shared(new_args.at(0), - new_args.at(1), - new_args.at(2), - get_window_movement_strides(), - get_window_dilation_strides(), - get_padding_below(), - get_padding_above(), - get_groups()); -} - -OutputVector op::v0::GroupConvolutionBackpropData::decompose_op() const -{ - auto filters = input_value(1); - auto output_delta = input_value(2); - auto data_shape = get_input_shape(0); - - NodeVector sliced_inputs; - - auto groups = get_groups(); - // slice data shape - data_shape[1] /= groups; - // slice delta - auto sliced_delta = builder::opset1::split(output_delta, groups, 1); - // slice filters - auto sliced_filters = builder::opset1::split(filters, groups, 0); - - auto num_spatials = get_window_movement_strides().size(); - - for (size_t i = 0; i < groups; ++i) - { - auto sliced_conv = std::make_shared( - data_shape, - sliced_filters[i], - sliced_delta[i], - get_window_movement_strides(), - get_window_dilation_strides(), - get_padding_below(), - get_padding_above(), - Strides(num_spatials, 1)); // default data dilation strides - - sliced_inputs.push_back(sliced_conv); - } - - size_t concatenation_axis = 1; - return {std::make_shared(sliced_inputs, concatenation_axis)}; -} diff --git a/ngraph/test/runtime/op/group_conv.hpp b/ngraph/test/runtime/op/group_conv.hpp deleted file mode 100644 index 088d9ca4be6..00000000000 --- a/ngraph/test/runtime/op/group_conv.hpp +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include "backend_visibility.hpp" -#include "ngraph/op/convolution.hpp" -#include "ngraph/op/op.hpp" -#include "ngraph/op/util/attr_types.hpp" -#include "ngraph/op/util/fused_op.hpp" - -NGRAPH_SUPPRESS_DEPRECATED_START - -namespace ngraph -{ - namespace op - { - namespace v0 - { - /// \brief Group Convolution - class BACKEND_API GroupConvolution : public ngraph::op::util::FusedOp - { - public: - static constexpr NodeTypeInfo type_info{"GroupConvolution", 0}; - const NodeTypeInfo& get_type_info() const override { return type_info; } - GroupConvolution() = default; - GroupConvolution(const Output& data_batch, - const Output& filters, - const Strides& window_movement_strides, - const Strides& window_dilation_strides, - const CoordinateDiff& padding_below, - const CoordinateDiff& padding_above, - const Strides& data_dilation_strides, - const size_t groups, - const PadType& pad_type = PadType::EXPLICIT); - - // constructor which accept groups included in filters shape. - GroupConvolution(const Output& data_batch, - const Output& filters, - const Strides& window_movement_strides, - const Strides& window_dilation_strides, - const CoordinateDiff& padding_below, - const CoordinateDiff& padding_above, - const Strides& data_dilation_strides, - const PadType& pad_type = PadType::EXPLICIT); - Shape get_weights_dimensions() const; - const Strides& get_window_movement_strides() const - { - return m_window_movement_strides; - } - const Strides& get_window_dilation_strides() const - { - return m_window_dilation_strides; - } - const CoordinateDiff& get_padding_below() const { return m_padding_below; } - const CoordinateDiff& get_padding_above() const { return m_padding_above; } - const Strides& get_data_dilation_strides() const { return m_data_dilation_strides; } - Output get_filters() { return input_value(1); } - Output get_data_batch() { return input_value(0); } - size_t get_groups() const { return m_groups; }; - const PadType& get_pad_type() const { return m_pad_type; } - virtual std::shared_ptr - clone_with_new_inputs(const OutputVector& new_args) const override; - - virtual OutputVector decompose_op() const override; - - virtual void pre_validate_and_infer_types() override; - virtual void post_validate_and_infer_types() override; - - bool has_groups_in_filters() const { return m_groups_in_filters; } - - protected: - Strides m_window_movement_strides; - Strides m_window_dilation_strides; - CoordinateDiff m_padding_below; - CoordinateDiff m_padding_above; - Strides m_data_dilation_strides; - size_t m_groups; - PadType m_pad_type{PadType::NOTSET}; - - private: - bool m_groups_in_filters; - }; - - /// \brief Group Convolution data batch backprop - class BACKEND_API GroupConvolutionBackpropData : public ngraph::op::util::FusedOp - { - public: - static constexpr NodeTypeInfo type_info{"GroupConvolutionBackpropData", 0}; - const NodeTypeInfo& get_type_info() const override { return type_info; } - GroupConvolutionBackpropData() = default; - GroupConvolutionBackpropData(const Output& data_batch, - const Output& filters, - const Output& output_delta, - const Strides& window_movement_strides, - const Strides& window_dilation_strides, - const CoordinateDiff& padding_below, - const CoordinateDiff& padding_above, - const size_t groups); - - const Strides& get_window_movement_strides() const - { - return m_window_movement_strides; - } - const Strides& get_window_dilation_strides() const - { - return m_window_dilation_strides; - } - const CoordinateDiff& get_padding_below() const { return m_padding_below; } - const CoordinateDiff& get_padding_above() const { return m_padding_above; } - size_t get_groups() const { return m_groups; }; - virtual std::shared_ptr - clone_with_new_inputs(const OutputVector& new_args) const override; - - virtual OutputVector decompose_op() const override; - - virtual void pre_validate_and_infer_types() override; - - protected: - Strides m_window_movement_strides; - Strides m_window_dilation_strides; - CoordinateDiff m_padding_below; - CoordinateDiff m_padding_above; - size_t m_groups; - }; - } - } // namespace op -} // namespace ngraph - -NGRAPH_SUPPRESS_DEPRECATED_END diff --git a/ngraph/test/runtime/opset0_tbl.hpp b/ngraph/test/runtime/opset0_tbl.hpp deleted file mode 100644 index d5eb01e1bfc..00000000000 --- a/ngraph/test/runtime/opset0_tbl.hpp +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -// This collection contains one entry for each op. If an op is added it must be -// added to this list. -// -// In order to use this list you want to define a macro named exactly NGRAPH_OP -// When you are done you should undef the macro -// As an example if you wanted to make a list of all op names as strings you could do this: -// -// #define NGRAPH_OP(a,b) #a, -// std::vector op_names{ -// #include "this include file name" -// }; -// #undef NGRAPH_OP -// -// This sample expands to a list like this: -// "Abs", -// "Acos", -// ... -// -// #define NGRAPH_OP(a,b) b::a, -// std::vector op_names{ -// #include "this include file name" -// }; -// #undef NGRAPH_OP -// -// This sample expands to a list like this: -// ngraph::op::Abs, -// ngraph::op::Acos, -// ... -// -// It's that easy. You can use this for fun and profit. - -#ifndef NGRAPH_OP -#warning "NGRAPH_OP not defined" -#define NGRAPH_OP(x, y) -#endif - -NGRAPH_OP(Abs, ngraph::op) -NGRAPH_OP(Acos, ngraph::op) -NGRAPH_OP(Asin, ngraph::op) -NGRAPH_OP(Atan, ngraph::op) -NGRAPH_OP(AvgPool, ngraph::op::v0) -NGRAPH_OP(BatchNormInference, ngraph::op::v0) -NGRAPH_OP(Broadcast, ngraph::op::v1) -NGRAPH_OP(Ceiling, ngraph::op) -NGRAPH_OP(Clamp, ngraph::op) -NGRAPH_OP(Concat, ngraph::op) -NGRAPH_OP(Constant, ngraph::op) -NGRAPH_OP(Convert, ngraph::op) -NGRAPH_OP(Convolution, ngraph::op::v0) -NGRAPH_OP(ConvolutionBackpropData, ngraph::op::v0) -NGRAPH_OP(Cos, ngraph::op) -NGRAPH_OP(Cosh, ngraph::op) -NGRAPH_OP(CumSum, ngraph::op::v0) -NGRAPH_OP(DepthToSpace, ngraph::op) -NGRAPH_OP(Elu, ngraph::op) -NGRAPH_OP(Erf, ngraph::op) -NGRAPH_OP(Exp, ngraph::op) -NGRAPH_OP(FakeQuantize, ngraph::op) -NGRAPH_OP(Floor, ngraph::op) -NGRAPH_OP(GRN, ngraph::op) -NGRAPH_OP(Gather, ngraph::op::v1) -NGRAPH_OP(Gelu, ngraph::op) -NGRAPH_OP(GroupConvolution, ngraph::op::v0) -NGRAPH_OP(GroupConvolutionBackpropData, ngraph::op::v0) -NGRAPH_OP(HardSigmoid, ngraph::op) -NGRAPH_OP(Interpolate, ngraph::op::v0) -NGRAPH_OP(Log, ngraph::op) -NGRAPH_OP(LRN, ngraph::op) -NGRAPH_OP(LSTMSequence, ngraph::op::v0) -NGRAPH_OP(MatMul, ngraph::op) -NGRAPH_OP(MVN, ngraph::op) -NGRAPH_OP(Negative, ngraph::op) -NGRAPH_OP(NormalizeL2, ngraph::op::v0) -NGRAPH_OP(Parameter, ngraph::op) -NGRAPH_OP(PRelu, ngraph::op) -NGRAPH_OP(PriorBox, ngraph::op) -NGRAPH_OP(Range, ngraph::op) -NGRAPH_OP(Relu, ngraph::op) -NGRAPH_OP(Result, ngraph::op) -NGRAPH_OP(ReverseSequence, ngraph::op) -NGRAPH_OP(Selu, ngraph::op) -NGRAPH_OP(ShapeOf, ngraph::op) -NGRAPH_OP(ShuffleChannels, ngraph::op) -NGRAPH_OP(Sigmoid, ngraph::op) -NGRAPH_OP(Sign, ngraph::op) -NGRAPH_OP(Sin, ngraph::op) -NGRAPH_OP(Sinh, ngraph::op) -NGRAPH_OP(SpaceToDepth, ngraph::op) -NGRAPH_OP(Sqrt, ngraph::op) -NGRAPH_OP(SquaredDifference, ngraph::op) -NGRAPH_OP(Squeeze, ngraph::op) -NGRAPH_OP(Tan, ngraph::op) -NGRAPH_OP(Tanh, ngraph::op) -NGRAPH_OP(TensorIterator, ngraph::op) -NGRAPH_OP(Tile, ngraph::op::v0) -NGRAPH_OP(Unsqueeze, ngraph::op::v0) -NGRAPH_OP(Xor, ngraph::op) diff --git a/ngraph/test/runtime/pass/fused_op_decomposition.cpp b/ngraph/test/runtime/pass/fused_op_decomposition.cpp deleted file mode 100644 index 89cbba09536..00000000000 --- a/ngraph/test/runtime/pass/fused_op_decomposition.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "fused_op_decomposition.hpp" -#include "ngraph/graph_util.hpp" -#include "ngraph/op/util/op_types.hpp" -#include "ngraph/provenance.hpp" - -using namespace std; -using namespace ngraph; - -NGRAPH_SUPPRESS_DEPRECATED_START - -pass::FusedOpDecomposition::FusedOpDecomposition(op_query_t callback) - : m_has_direct_support{callback} -{ -} - -bool pass::FusedOpDecomposition::run_on_node(shared_ptr node) -{ - bool modified = false; - - if (op::supports_decompose(node)) - { - if (m_has_direct_support && m_has_direct_support(*node)) - { - // Op supported by backend. Do not decompose - return modified; - } - - OutputVector output_vector = node->decompose_op(); - NodeVector subgraph_outputs = as_node_vector(output_vector); - - if (ngraph::get_provenance_enabled()) - { - // Capture the input values as an edge for provenance - auto base_input_values = node->input_values(); - auto provenance_tags = node->get_provenance_tags(); - const std::string tag = "get_type_name()) + ">"; - provenance_tags.insert(tag); - - // Transfer the new provenance tags to the newly created ops - for (auto output_node : subgraph_outputs) - { - output_node->add_provenance_tags_above(base_input_values, provenance_tags); - } - } - - // Run recursively until no more fused ops - auto subgraph = extract_subgraph(subgraph_outputs, as_node_vector(node->input_values())); - for (auto subgraph_node : subgraph) - { - run_on_node(subgraph_node); - } - - size_t i = 0; - for (auto output_node : subgraph_outputs) - { - for (size_t j = 0; j < output_node->outputs().size(); j++, i++) - { - std::set> fop_users = node->outputs().at(i).get_target_inputs(); - for (auto fop_user : fop_users) - { - fop_user.replace_source_output(output_node->output(j)); - } - } - } - if (i != node->get_output_size()) - { - throw ngraph_error("While replacing " + node->get_name() + - ", mismatch between op output count and outputs of the decomposed " - "subgraph. Expected: " + - to_string(node->get_output_size()) + " Got: " + to_string(i)); - } - modified = true; - } - - return modified; -} diff --git a/ngraph/test/runtime/pass/fused_op_decomposition.hpp b/ngraph/test/runtime/pass/fused_op_decomposition.hpp deleted file mode 100644 index e1b7fdcfc35..00000000000 --- a/ngraph/test/runtime/pass/fused_op_decomposition.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include - -#include "backend_visibility.hpp" -#include "ngraph/pass/pass.hpp" - -NGRAPH_SUPPRESS_DEPRECATED_START - -namespace ngraph -{ - namespace pass - { - /// \brief The FusedOpDecomposition pass is used to decompose a fused op - /// into a sub-graph of supported ops if the fused op is not supported by - /// the backend. - /// - /// \details By default, the pass decomposes a fused op if it is not - /// supported by the backend and runs recursively until no more fused ops - /// can be found or the new ops are supported by the backend. - /// If the backend supports a fused op, then it can provide a callback - /// function while registering the pass. The callback function can then - /// provide logic to prevent decomposing the supported op. - /// It also adds provenance tags along the way to each op for easy reference - /// and debugging. - /// - /// In the example shown below, the original graph has a fused GeLU op. - /// After applying this pass, the GeLU op is decomposed into group of ops which - /// together perform the same operation as GeLU. - /// - /// - /// - /// - /// - /// - /// - /// - ///
Before the pass After the pass
\image html decompose_gelu_pre.svg \image html decompose_gelu_post.svg
- class BACKEND_API FusedOpDecomposition : public NodePass - { - public: /// \brief Function signature type for callback used to check whether provided node - /// is supported by backend. - using op_query_t = std::function; - - /// - /// \brief Constructor for the Fused operation decomposition pass. - /// - /// \param[in] callback The function object used to determine whether current backend - /// provide direct support for passed node. Should have signature: - /// bool fn(const Node&) - /// - FusedOpDecomposition(op_query_t callback = nullptr); - bool run_on_node(std::shared_ptr node) override; - - private: - /// \brief A function returning whether provided Node is supported by current backend. - /// The returned bool value is used to control whether decompose operator or not. - op_query_t m_has_direct_support = nullptr; - }; - } -} - -NGRAPH_SUPPRESS_DEPRECATED_END diff --git a/ngraph/test/runtime/pass/implicit_broadcast_elimination.cpp b/ngraph/test/runtime/pass/implicit_broadcast_elimination.cpp deleted file mode 100644 index ce380781e79..00000000000 --- a/ngraph/test/runtime/pass/implicit_broadcast_elimination.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "implicit_broadcast_elimination.hpp" - -#include "ngraph/builder/autobroadcast.hpp" -#include "ngraph/graph_util.hpp" -#include "ngraph/op/util/binary_elementwise_arithmetic.hpp" -#include "ngraph/op/util/binary_elementwise_comparison.hpp" -#include "ngraph/op/util/binary_elementwise_logical.hpp" -#include "ngraph/op/util/op_types.hpp" - -NGRAPH_SUPPRESS_DEPRECATED_START - -using namespace std; -using namespace ngraph; - -bool ngraph::pass::ImplicitBroadcastElimination::run_on_node(std::shared_ptr node) -{ - if (ngraph::op::supports_auto_broadcast(node)) - { - if (node->get_autob().m_type != op::AutoBroadcastType::NONE) - { - auto new_args = pass::explicit_broadcast(node); - for (size_t i = 0; i < new_args.size(); i++) - { - node->input(i).replace_source_output(new_args[i]->output(0)); - } - return true; - } - } - return false; -} - -NodeVector ngraph::pass::explicit_broadcast(std::shared_ptr& node) -{ - NodeVector rc; - if (ngraph::op::supports_auto_broadcast(node)) - { - auto autob = node->get_autob(); - if (autob.m_type == op::AutoBroadcastType::NONE) - { - for (auto& val : node->input_values()) - rc.emplace_back(val.get_node_shared_ptr()); - } - else if (autob.m_type == op::AutoBroadcastType::NUMPY) - { - rc = as_node_vector(builder::numpy_broadcast_outputs(node->input_values())); - } - else if (autob.m_type == op::AutoBroadcastType::PDPD) - { - rc = as_node_vector(builder::pdpd_broadcast(node->input_values(), autob.m_axis)); - } - else - { - throw ngraph_error("Unsupported implicit broadcast type"); - } - } - return rc; -} diff --git a/ngraph/test/runtime/pass/implicit_broadcast_elimination.hpp b/ngraph/test/runtime/pass/implicit_broadcast_elimination.hpp deleted file mode 100644 index 939c2b2073c..00000000000 --- a/ngraph/test/runtime/pass/implicit_broadcast_elimination.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include "backend_visibility.hpp" -#include "ngraph/node.hpp" -#include "ngraph/pass/pass.hpp" - -NGRAPH_SUPPRESS_DEPRECATED_START - -namespace ngraph -{ - namespace pass - { - NodeVector explicit_broadcast(std::shared_ptr& node); - class ImplicitBroadcastElimination; - } -} - -class BACKEND_API ngraph::pass::ImplicitBroadcastElimination : public ngraph::pass::NodePass -{ -public: - bool run_on_node(std::shared_ptr node) override; -}; - -NGRAPH_SUPPRESS_DEPRECATED_END diff --git a/ngraph/test/runtime/pass/liveness.cpp b/ngraph/test/runtime/pass/liveness.cpp deleted file mode 100644 index bb0b9487a6e..00000000000 --- a/ngraph/test/runtime/pass/liveness.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include -#include -#include - -#include "liveness.hpp" -#include "ngraph/descriptor/input.hpp" -#include "ngraph/descriptor/output.hpp" -#include "ngraph/function.hpp" -#include "ngraph/graph_util.hpp" -#include "ngraph/log.hpp" -#include "ngraph/node.hpp" -#include "ngraph/op/constant.hpp" -#include "ngraph/op/parameter.hpp" -#include "ngraph/op/result.hpp" -#include "ngraph/util.hpp" - -using namespace std; -using namespace ngraph; - -bool pass::Liveness::run_on_function(shared_ptr function) -{ - auto ops = function->get_ordered_ops(); - - unordered_set persistent_tensors; - unordered_set output_tensors; - for (const shared_ptr& node : function->get_parameters()) - { - for (auto& output : node->outputs()) - { - descriptor::Tensor& tensor = output.get_tensor(); - persistent_tensors.insert(&tensor); - } - } - for (const shared_ptr& node : function->get_results()) - { - for (auto& output : node->outputs()) - { - descriptor::Tensor& tensor = output.get_tensor(); - persistent_tensors.insert(&tensor); - output_tensors.insert(&tensor); - } - } - for (const shared_ptr& node : ops) - { - if (auto constant_node = as_type_ptr(node)) - { - for (auto& output : constant_node->outputs()) - { - descriptor::Tensor& tensor = output.get_tensor(); - persistent_tensors.insert(&tensor); - } - } - } - - unordered_set currently_live; - for (auto it = ops.rbegin(); it != ops.rend(); it++) - { - const shared_ptr& node = *it; - node->liveness_new_list.clear(); - node->liveness_free_list.clear(); - unordered_set input_tensor_decls; - for (auto& input : node->inputs()) - { - descriptor::Tensor& tensor = input.get_tensor(); - if (persistent_tensors.find(&tensor) == persistent_tensors.end()) - { - input_tensor_decls.insert(&tensor); - } - } - - unordered_set output_tensor_decls; - for (auto& output : node->outputs()) - { - descriptor::Tensor& tensor = output.get_tensor(); - if (persistent_tensors.find(&tensor) == persistent_tensors.end()) - { - output_tensor_decls.insert(&tensor); - } - } - - unordered_set free_tensor_decls; - unordered_set new_tensor_decls; - unordered_set all_tensor_decls = input_tensor_decls; - all_tensor_decls.insert(output_tensor_decls.begin(), output_tensor_decls.end()); - - for (descriptor::Tensor* tensor_decl : all_tensor_decls) - { - if (currently_live.find(tensor_decl) == currently_live.end()) - { - // this is the last node that value is seen in - // delete it at the end of the op - currently_live.insert(tensor_decl); - if (output_tensors.find(tensor_decl) == output_tensors.end()) - { - // Don't free output tensors - free_tensor_decls.insert(tensor_decl); - } - } - } - - for (descriptor::Tensor* output_decl : output_tensor_decls) - { - auto currently_live_it = currently_live.find(output_decl); - if (currently_live_it != currently_live.end()) - { - new_tensor_decls.insert(output_decl); - currently_live.erase(currently_live_it); - } - } - node->liveness_free_list = free_tensor_decls; - node->liveness_new_list = new_tensor_decls; - } - - return false; -} diff --git a/ngraph/test/runtime/pass/liveness.hpp b/ngraph/test/runtime/pass/liveness.hpp deleted file mode 100644 index 64aff0bc8e0..00000000000 --- a/ngraph/test/runtime/pass/liveness.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include "backend_visibility.hpp" -#include "ngraph/descriptor/tensor.hpp" -#include "ngraph/pass/pass.hpp" - -namespace ngraph -{ - namespace pass - { - class Liveness; - } -} - -class BACKEND_API ngraph::pass::Liveness : public FunctionPass -{ -public: - bool run_on_function(std::shared_ptr) override; -}; diff --git a/ngraph/test/runtime/pass/opset0_downgrade.cpp b/ngraph/test/runtime/pass/opset0_downgrade.cpp deleted file mode 100644 index 4d48854bf6b..00000000000 --- a/ngraph/test/runtime/pass/opset0_downgrade.cpp +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include -#include -#include -#include - -#include "ngraph/builder/autobroadcast.hpp" -#include "ngraph/builder/reshape.hpp" -#include "ngraph/graph_util.hpp" -#include "ngraph/node.hpp" -#include "ngraph/op/util/attr_types.hpp" -#include "ngraph/op/util/op_types.hpp" -#include "ngraph/ops.hpp" -#include "ngraph/provenance.hpp" -#include "ngraph/slice_plan.hpp" -#include "ngraph/type.hpp" -#include "ngraph/validation_util.hpp" -#include "op/avg_pool.hpp" -#include "pass/implicit_broadcast_elimination.hpp" -#include "pass/opset0_downgrade.hpp" - -NGRAPH_SUPPRESS_DEPRECATED_START - -using namespace std; -using namespace ngraph; - -namespace opset0_downgrade -{ - template - shared_ptr op_cast_binary_elementwise_node(const shared_ptr& node) - { - const auto input_arg0 = node->input_value(0); - const auto input_arg1 = node->input_value(1); - const auto autob = node->get_autob(); - auto replacement_node = make_shared(input_arg0, input_arg1, autob); - replace_node(node, replacement_node); - return replacement_node; - } - - template - shared_ptr op_cast_reduction_node(const shared_ptr& node) - { - auto replacement_node = make_shared(node->input_value(0), node->input_value(1)); - if (node->get_keep_dims()) - { - string v1_op_name = string{node->get_type_name()} + ":v1"; - string v0_op_name = string{OpV0{}.get_type_name()} + ":v0"; - - NGRAPH_CHECK(node->reduction_axes_constant(), - "Unable to convert ", - v1_op_name, - "to ", - v0_op_name, - " if reduction axes are not constant (for keep_dims=true). Node: ", - *node); - auto output_pshape = replacement_node->get_output_partial_shape(0); - NGRAPH_CHECK(output_pshape.is_static(), - "Unable to convert ", - v1_op_name, - "to ", - v0_op_name, - " if output shape is dynamic (for keep_dims=true). Node: ", - *node); - const auto output_shape = output_pshape.to_shape(); - auto reshaped_output_shape = output_shape; - for (const auto& axis : node->get_reduction_axes()) - { - reshaped_output_shape.insert(reshaped_output_shape.begin() + axis, 1); - } - auto shape_pattern = op::Constant::create( - element::u64, {reshaped_output_shape.size()}, reshaped_output_shape); - auto reshaped_product = - make_shared(replacement_node->output(0), shape_pattern, false); - return reshaped_product; - } - else - { - return replacement_node; - } - } - - // Default is that we did nothing - shared_ptr op_cast(shared_ptr node) { return nullptr; } - shared_ptr op_cast(shared_ptr node) - { - return op_cast_binary_elementwise_node(node); - } - - using DispatchMap = map node)>>; - - template - bool op_cast_thunk(shared_ptr node) - { - auto downgraded_node = op_cast(as_type_ptr(node)); - if (downgraded_node) - { - if (ngraph::get_provenance_enabled()) - { - const std::string provenance_tag = - "get_type_name()) + ")>"; - downgraded_node->add_provenance_tags_above(node->input_values(), {provenance_tag}); - } - return true; - } - return false; - } - - DispatchMap& get_dispatch_map() - { - static DispatchMap dispatch_map{ -#define NGRAPH_OP(NAME, NAMESPACE) {NAMESPACE::NAME::type_info, op_cast_thunk}, -#include "ngraph/opsets/opset1_tbl.hpp" -#undef NGRAPH_OP - }; - return dispatch_map; - } -} // namespace opset0_downgrade - -bool pass::Opset0Downgrade::run_on_node(shared_ptr node) -{ - bool modified = false; - auto& dispatch_map = opset0_downgrade::get_dispatch_map(); - auto it = dispatch_map.find(node->get_type_info()); - if (it != dispatch_map.end()) - { - modified = it->second(node); - } - return modified; -} diff --git a/ngraph/test/runtime/pass/opset0_downgrade.hpp b/ngraph/test/runtime/pass/opset0_downgrade.hpp deleted file mode 100644 index 96a831d9c9f..00000000000 --- a/ngraph/test/runtime/pass/opset0_downgrade.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include "backend_visibility.hpp" -#include "ngraph/pass/pass.hpp" - -NGRAPH_SUPPRESS_DEPRECATED_START - -namespace ngraph -{ - namespace pass - { - class BACKEND_API Opset0Downgrade : public NodePass - { - public: - /// - /// \brief Constructor for the Opv1 downgrade transformation pass. - /// - /// \details This transformation pass iterates over all nodes in a graph - /// and updates version 1 ops to their version 0 equivalents. - /// All ops in the final graph have op version 0. - Opset0Downgrade() = default; - bool run_on_node(std::shared_ptr node) override; - }; - } -} - -NGRAPH_SUPPRESS_DEPRECATED_END diff --git a/ngraph/test/runtime/pass/opset1_downgrade.cpp b/ngraph/test/runtime/pass/opset1_downgrade.cpp deleted file mode 100644 index 1d77d39b8aa..00000000000 --- a/ngraph/test/runtime/pass/opset1_downgrade.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include "ngraph/node.hpp" -#include "ngraph/ops.hpp" -#include "ngraph/provenance.hpp" -#include "ngraph/validation_util.hpp" -#include "opset1_downgrade.hpp" - -using namespace std; -using namespace ngraph; - -namespace opset1_downgrade -{ - shared_ptr op_cast(shared_ptr node) - { - const auto data = node->input_value(0).get_node_shared_ptr(); - const auto target_shape = node->input_value(1).get_node_shared_ptr(); - - shared_ptr replacement_node; - switch (node->get_broadcast_spec().m_type) - { - case op::BroadcastType::BIDIRECTIONAL: - { - const auto const_filled_with_ones = make_shared( - op::Constant::create(data->get_element_type(), {}, {1}), target_shape); - if (const_filled_with_ones->get_element_type() == element::boolean) - { - replacement_node = make_shared(data, const_filled_with_ones); - } - else - { - replacement_node = make_shared(data, const_filled_with_ones); - } - break; - } - case op::BroadcastType::EXPLICIT: - { - const auto axes_mapping = node->input_value(2).get_node_shared_ptr(); - replacement_node = make_shared( - data, target_shape, axes_mapping, op::AutoBroadcastType::EXPLICIT); - break; - } - case op::BroadcastType::NUMPY: - { - replacement_node = - make_shared(data, target_shape, op::AutoBroadcastType::NUMPY); - break; - } - case op::BroadcastType::PDPD: - { - op::AutoBroadcastSpec broadcast_spec; - broadcast_spec.m_type = op::AutoBroadcastType::PDPD; - broadcast_spec.m_axis = node->get_broadcast_spec().m_axis; - replacement_node = make_shared(data, target_shape, broadcast_spec); - break; - } - default: - { - NGRAPH_CHECK( - true, - "Not supported broadcast type during Broadcast:v3 to Broadcast:v1 conversion. ", - "Node: ", - *node); - } - } - replace_node(node, replacement_node); - return replacement_node; - } - - shared_ptr op_cast(shared_ptr node) - { - const auto data = node->input_value(0); - const auto k = node->input_value(1); - const auto replacement_node = make_shared(data, - k, - node->get_axis(), - node->get_mode(), - node->get_sort_type(), - node->get_index_element_type()); - replace_node(node, replacement_node); - return replacement_node; - } - - using DispatchMap = map node)>>; - - template - bool op_cast_thunk(shared_ptr node) - { - auto downgraded_node = op_cast(as_type_ptr(node)); - if (downgraded_node) - { - if (ngraph::get_provenance_enabled()) - { - const std::string provenance_tag = - "get_type_name()) + ")>"; - downgraded_node->add_provenance_tags_above(node->input_values(), {provenance_tag}); - } - return true; - } - return false; - } - - DispatchMap& get_dispatch_map() - { - static DispatchMap dispatch_map{ -#define NGRAPH_OP(NAME, NAMESPACE) {NAMESPACE::NAME::type_info, op_cast_thunk}, - NGRAPH_OP(Broadcast, op::v3) NGRAPH_OP(TopK, op::v3) -#undef NGRAPH_OP - }; - return dispatch_map; - } -} // namespace opset1_downgrade - -bool pass::Opset1Downgrade::run_on_node(shared_ptr node) -{ - bool modified = false; - auto& dispatch_map = opset1_downgrade::get_dispatch_map(); - auto it = dispatch_map.find(node->get_type_info()); - if (it != dispatch_map.end()) - { - modified = it->second(node); - } - return modified; -} diff --git a/ngraph/test/runtime/pass/opset1_downgrade.hpp b/ngraph/test/runtime/pass/opset1_downgrade.hpp deleted file mode 100644 index 52e9d8397bc..00000000000 --- a/ngraph/test/runtime/pass/opset1_downgrade.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include "backend_visibility.hpp" -#include "ngraph/pass/pass.hpp" - -NGRAPH_SUPPRESS_DEPRECATED_START - -namespace ngraph -{ - namespace pass - { - class BACKEND_API Opset1Downgrade : public NodePass - { - public: - /// - /// \brief Constructor for the Opv1 downgrade transformation pass. - /// - /// \details This transformation pass iterates over all nodes in a graph - /// and updates version 3 ops to their version 1 equivalents. - /// All ops in the final graph have op version 1. - Opset1Downgrade() = default; - bool run_on_node(std::shared_ptr node) override; - }; - } -} - -NGRAPH_SUPPRESS_DEPRECATED_END diff --git a/ngraph/test/runtime/pass/opset1_upgrade.cpp b/ngraph/test/runtime/pass/opset1_upgrade.cpp deleted file mode 100644 index 9c8f2d4c8e7..00000000000 --- a/ngraph/test/runtime/pass/opset1_upgrade.cpp +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "opset1_upgrade.hpp" - -#include -#include -#include -#include - -#include "ngraph/builder/autobroadcast.hpp" -#include "ngraph/builder/reshape.hpp" -#include "ngraph/graph_util.hpp" -#include "ngraph/op/util/op_types.hpp" -#include "ngraph/ops.hpp" -#include "ngraph/provenance.hpp" -#include "op/avg_pool.hpp" -#include "op/convolution.hpp" -#include "op/group_conv.hpp" - -NGRAPH_SUPPRESS_DEPRECATED_START - -using namespace std; -using namespace ngraph; - -namespace opset1_upgrade -{ - template - shared_ptr op_cast_binary_elementwise_node(const shared_ptr& node) - { - const auto autob = node->get_autob(); - auto replacement_node = - make_shared(node->input_value(0), node->input_value(1), autob); - replace_node(node, replacement_node); - return replacement_node; - } - - // Default is that we didn nothing - shared_ptr op_cast(shared_ptr node) { return nullptr; } - shared_ptr op_cast(shared_ptr node) - { - auto data_batch_shape = node->get_data_batch_shape(); - auto strides = node->get_window_movement_strides_forward(); - auto dilations = node->get_window_dilation_strides_forward(); - auto pads_begin = node->get_padding_below_forward(); - auto pads_end = node->get_padding_above_forward(); - auto data_dilation_strides = node->get_data_dilation_strides_forward(); - - bool is_dds_valid = all_of(data_dilation_strides.begin(), - data_dilation_strides.end(), - [](size_t value) { return value == 1; }); - - NGRAPH_CHECK(is_dds_valid, - "Unable to convert ConvolutionBackpropData:0 to ConvolutionBackpropData:1 " - "with data dilation strides " - "other than `1`. Node: ", - *node); - - auto replacement_node = make_shared( - node->input_value(1), // data - node->input_value(0), // filters - op::Constant::create( - element::i64, - Shape{data_batch_shape.size() - 2}, - vector(data_batch_shape.begin() + 2, data_batch_shape.end())), - strides, - pads_begin, - pads_end, - dilations); - replace_node(node, replacement_node); - return replacement_node; - } - - shared_ptr op_cast(shared_ptr node) - { - auto strides = node->get_window_movement_strides(); - auto dilations = node->get_window_dilation_strides(); - auto pads_begin = node->get_padding_below(); - auto pads_end = node->get_padding_above(); - auto data_dilation_strides = node->get_data_dilation_strides(); - auto auto_pad = node->get_pad_type(); - - bool is_dds_valid = all_of(data_dilation_strides.begin(), - data_dilation_strides.end(), - [](size_t value) { return value == 1; }); - - NGRAPH_CHECK(is_dds_valid, - "Unable to convert GroupConvolution:0 to GroupConvolution:1" - "with data dilation strides other than `1`. Node: ", - *node); - - shared_ptr replacement_node; - if (node->has_groups_in_filters()) - { - replacement_node = make_shared(node->input_value(0), - node->input_value(1), - strides, - pads_begin, - pads_end, - dilations, - auto_pad); - } - else - { - NGRAPH_CHECK(node->get_input_partial_shape(1).is_static(), - "Unable to convert GroupConvolution:0 to GroupConvolution:1" - "with dynamic filters shape. Node: ", - *node); - - auto filters_shape = node->get_input_shape(1); - auto groups = node->get_groups(); - filters_shape[0] /= groups; - filters_shape.insert(filters_shape.begin(), groups); - - auto reshaped_filters = builder::opset1::reshape(node->input_value(1), filters_shape); - - replacement_node = make_shared(node->input_value(0), - reshaped_filters, - strides, - pads_begin, - pads_end, - dilations, - auto_pad); - } - replace_node(node, replacement_node); - return replacement_node; - } - - shared_ptr op_cast(shared_ptr node) - { - const auto strides = node->get_window_movement_strides(); - const auto dilations = node->get_window_dilation_strides(); - const auto pads_begin = node->get_padding_below(); - const auto pads_end = node->get_padding_above(); - - const auto data_batch_pshape = node->get_input_partial_shape(0); - const auto filters_pshape = node->get_input_partial_shape(1); - - NGRAPH_CHECK(data_batch_pshape.is_static(), - "Unable to convert GroupConvolutionBackpropData:0 to " - "GroupConvolutionBackpropData:1 with dynamic data_batch shape. Node: ", - *node); - NGRAPH_CHECK(filters_pshape.is_static(), - "Unable to convert GroupConvolutionBackpropData:0 to " - "GroupConvolutionBackpropData:1 with dynamic filters shape. Node: ", - *node); - - auto data_batch_shape = data_batch_pshape.to_shape(); - // Remove N, C from output shape to preserve only spatial dimentions. - data_batch_shape.erase(std::begin(data_batch_shape), - std::next(std::begin(data_batch_shape), 2)); - auto filters_shape = filters_pshape.to_shape(); - auto groups = node->get_groups(); - - filters_shape[0] /= groups; - filters_shape.insert(filters_shape.begin(), groups); - auto reshaped_filters = builder::opset1::reshape(node->input_value(1), filters_shape); - - auto replacement_node = make_shared( - node->input_value(2), - reshaped_filters, - op::Constant::create(element::i64, Shape{data_batch_shape.size()}, data_batch_shape), - strides, - pads_begin, - pads_end, - dilations); - replace_node(node, replacement_node); - return replacement_node; - } - - shared_ptr op_cast(shared_ptr node) - { - auto replacement_node = make_shared( - node->input_value(0), node->input_value(1), node->get_autob()); - replace_node(node, replacement_node); - return replacement_node; - } - - using DispatchMap = map node)>>; - - template - bool op_cast_thunk(shared_ptr node) - { - auto upgraded_node = op_cast(as_type_ptr(node)); - if (upgraded_node) - { - if (ngraph::get_provenance_enabled()) - { - const std::string provenance_tag = - "get_type_name()) + ")>"; - upgraded_node->add_provenance_tags_above(node->input_values(), {provenance_tag}); - } - return true; - } - return false; - } - - DispatchMap& get_dispatch_map() - { - NGRAPH_SUPPRESS_DEPRECATED_START - static DispatchMap dispatch_map{ -#define NGRAPH_OP(NAME, NAMESPACE) {NAMESPACE::NAME::type_info, op_cast_thunk}, -#include "opset0_tbl.hpp" -#undef NGRAPH_OP - }; - return dispatch_map; - NGRAPH_SUPPRESS_DEPRECATED_END - } -} // namespace opset1_upgrade - -bool pass::Opset1Upgrade::run_on_node(shared_ptr node) -{ - bool modified = false; - auto& dispatch_map = opset1_upgrade::get_dispatch_map(); - auto it = dispatch_map.find(node->get_type_info()); - if (it != dispatch_map.end()) - { - modified = it->second(node); - } - return modified; -} diff --git a/ngraph/test/runtime/pass/opset1_upgrade.hpp b/ngraph/test/runtime/pass/opset1_upgrade.hpp deleted file mode 100644 index c1942626fe3..00000000000 --- a/ngraph/test/runtime/pass/opset1_upgrade.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include "backend_visibility.hpp" -#include "ngraph/pass/pass.hpp" - -NGRAPH_SUPPRESS_DEPRECATED_START - -namespace ngraph -{ - namespace pass - { - class BACKEND_API Opset1Upgrade : public NodePass - { - public: - /// - /// \brief Constructor for the Opset1Upgrade transformation pass. - /// - /// \details This transformation pass iterates over all nodes in a graph - /// and updates version 0 ops to their version 1 equivalents. - /// All ops in the final graph have op version 1. - Opset1Upgrade() = default; - bool run_on_node(std::shared_ptr node) override; - }; - } -} - -NGRAPH_SUPPRESS_DEPRECATED_END diff --git a/ngraph/test/tensor.cpp b/ngraph/test/tensor.cpp index 6b4c3597eeb..4deaadb3b75 100644 --- a/ngraph/test/tensor.cpp +++ b/ngraph/test/tensor.cpp @@ -13,7 +13,6 @@ #include "ngraph/ngraph.hpp" #include "ngraph/opsets/opset6.hpp" #include "ngraph/pass/manager.hpp" -#include "pass/liveness.hpp" #include "util/test_tools.hpp" NGRAPH_SUPPRESS_DEPRECATED_START @@ -21,66 +20,6 @@ NGRAPH_SUPPRESS_DEPRECATED_START using namespace std; using namespace ngraph; -TEST(tensor, size) -{ - pass::Manager pass_manager; - - pass_manager.register_pass(); - - { - auto arg0 = make_shared(element::f32, Shape{2, 3}); - auto add = make_shared(arg0, arg0); - auto f0 = make_shared(add, ParameterVector{arg0}); - - pass_manager.run_passes(f0); - - ASSERT_EQ(1, arg0->get_output_size()); - descriptor::Tensor& output = arg0->get_output_tensor(0); - EXPECT_EQ(2 * 3 * 4, output.size()); - } - - { - auto arg0 = make_shared(element::f32, Shape{}); - auto add = make_shared(arg0, arg0); - auto f0 = make_shared(add, ParameterVector{arg0}); - - pass_manager.run_passes(f0); - - ASSERT_EQ(1, arg0->get_output_size()); - descriptor::Tensor& output = arg0->get_output_tensor(0); - EXPECT_EQ(1 * 4, output.size()); - } - - { - auto arg0 = make_shared(element::f32, Shape{1}); - auto add = make_shared(arg0, arg0); - auto f0 = make_shared(add, ParameterVector{arg0}); - - pass_manager.run_passes(f0); - - ASSERT_EQ(1, arg0->get_output_size()); - descriptor::Tensor& output = arg0->get_output_tensor(0); - EXPECT_EQ(1 * 4, output.size()); - } -} - -TEST(tensor, output_flag) -{ - pass::Manager pass_manager; - pass_manager.register_pass(); - - auto arg0 = make_shared(element::f32, Shape{1}); - auto add = make_shared(arg0, arg0); - auto f0 = make_shared(add, ParameterVector{arg0}); - - pass_manager.run_passes(f0); - - for (size_t i = 0; i < f0->get_output_size(); ++i) - { - EXPECT_TRUE(op::is_output(f0->get_output_op(i))); - } -} - TEST(tensor, tensor_names) { auto arg0 = make_shared(element::f32, Shape{1}); diff --git a/ngraph/test/type_prop/convolution.cpp b/ngraph/test/type_prop/convolution.cpp index fdd757da1a6..1e13c890a1e 100644 --- a/ngraph/test/type_prop/convolution.cpp +++ b/ngraph/test/type_prop/convolution.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "op/convolution.hpp" #include "gtest/gtest.h" #include "ngraph/ngraph.hpp" #include "util/type_prop.hpp" @@ -10,2234 +9,6 @@ using namespace std; using namespace ngraph; -TEST(type_prop, conv_1d_deduce) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 100}); - auto param1 = make_shared(element::f32, Shape{128, 3, 10}); - auto conv = make_shared(param0, param1); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 91})); - - EXPECT_EQ(conv->get_window_movement_strides(), Strides{1}); - EXPECT_EQ(conv->get_window_dilation_strides(), Strides{1}); - EXPECT_EQ(conv->get_data_dilation_strides(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below(), CoordinateDiff{0}); - EXPECT_EQ(conv->get_padding_above(), CoordinateDiff{0}); -} - -TEST(type_prop, conv_1d_deduce_padded) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 100}); - auto param1 = make_shared(element::f32, Shape{128, 3, 10}); - auto move_strides = Strides{1}; - auto dilation_strides = Strides{1}; - auto padding_below = CoordinateDiff{2}; - auto padding_above = CoordinateDiff{3}; - auto conv = make_shared( - param0, param1, move_strides, dilation_strides, padding_below, padding_above); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 96})); - - EXPECT_EQ(conv->get_window_movement_strides(), Strides{1}); - EXPECT_EQ(conv->get_window_dilation_strides(), Strides{1}); - EXPECT_EQ(conv->get_data_dilation_strides(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below(), CoordinateDiff{2}); - EXPECT_EQ(conv->get_padding_above(), CoordinateDiff{3}); -} - -TEST(type_prop, conv_1d_deduce_strided) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 100}); - auto param1 = make_shared(element::f32, Shape{128, 3, 10}); - auto move_strides = Strides{2}; - auto conv = make_shared(param0, param1, move_strides); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 46})); - - EXPECT_EQ(conv->get_window_movement_strides(), Strides{2}); - EXPECT_EQ(conv->get_window_dilation_strides(), Strides{1}); - EXPECT_EQ(conv->get_data_dilation_strides(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below(), CoordinateDiff{0}); - EXPECT_EQ(conv->get_padding_above(), CoordinateDiff{0}); -} - -TEST(type_prop, conv_1d_deduce_strided_padded) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 100}); - auto param1 = make_shared(element::f32, Shape{128, 3, 10}); - auto move_strides = Strides{2}; - auto dilation_strides = Strides{1}; - auto padding_below = CoordinateDiff{2}; - auto padding_above = CoordinateDiff{3}; - auto conv = make_shared( - param0, param1, move_strides, dilation_strides, padding_below, padding_above); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 48})); - - EXPECT_EQ(conv->get_window_movement_strides(), Strides{2}); - EXPECT_EQ(conv->get_window_dilation_strides(), Strides{1}); - EXPECT_EQ(conv->get_data_dilation_strides(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below(), CoordinateDiff{2}); - EXPECT_EQ(conv->get_padding_above(), CoordinateDiff{3}); -} - -TEST(type_prop, conv_1d_deduce_strided_small_uneven) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 5}); - auto param1 = make_shared(element::f32, Shape{128, 3, 2}); - auto move_strides = Strides{2}; - auto conv = make_shared(param0, param1, move_strides); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 2})); - - EXPECT_EQ(conv->get_window_movement_strides(), Strides{2}); - EXPECT_EQ(conv->get_window_dilation_strides(), Strides{1}); - EXPECT_EQ(conv->get_data_dilation_strides(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below(), CoordinateDiff{0}); - EXPECT_EQ(conv->get_padding_above(), CoordinateDiff{0}); -} - -TEST(type_prop, conv_1d_deduce_strided_small_even) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 6}); - auto param1 = make_shared(element::f32, Shape{128, 3, 2}); - auto move_strides = Strides{2}; - auto conv = make_shared(param0, param1, move_strides); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 3})); - - EXPECT_EQ(conv->get_window_movement_strides(), Strides{2}); - EXPECT_EQ(conv->get_window_dilation_strides(), Strides{1}); - EXPECT_EQ(conv->get_data_dilation_strides(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below(), CoordinateDiff{0}); - EXPECT_EQ(conv->get_padding_above(), CoordinateDiff{0}); -} - -TEST(type_prop, conv_1d_deduce_window_dilated) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 100}); - auto param1 = make_shared(element::f32, Shape{128, 3, 10}); - auto move_strides = Strides{1}; - auto dilate_strides = Strides{2}; - auto conv = make_shared(param0, param1, move_strides, dilate_strides); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 82})); - - EXPECT_EQ(conv->get_window_movement_strides(), Strides{1}); - EXPECT_EQ(conv->get_window_dilation_strides(), Strides{2}); - EXPECT_EQ(conv->get_data_dilation_strides(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below(), CoordinateDiff{0}); - EXPECT_EQ(conv->get_padding_above(), CoordinateDiff{0}); -} - -TEST(type_prop, conv_1d_deduce_window_dilated_padded) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 100}); - auto param1 = make_shared(element::f32, Shape{128, 3, 10}); - auto move_strides = Strides{1}; - auto dilate_strides = Strides{2}; - auto padding_below = CoordinateDiff{2}; - auto padding_above = CoordinateDiff{3}; - auto conv = make_shared( - param0, param1, move_strides, dilate_strides, padding_below, padding_above); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 87})); - - EXPECT_EQ(conv->get_window_movement_strides(), Strides{1}); - EXPECT_EQ(conv->get_window_dilation_strides(), Strides{2}); - EXPECT_EQ(conv->get_data_dilation_strides(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below(), CoordinateDiff{2}); - EXPECT_EQ(conv->get_padding_above(), CoordinateDiff{3}); -} - -TEST(type_prop, conv_1d_deduce_window_dilated_data_dilated_padded) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 100}); - auto param1 = make_shared(element::f32, Shape{128, 3, 10}); - auto move_strides = Strides{1}; - auto dilate_strides = Strides{2}; - auto padding_below = CoordinateDiff{2}; - auto padding_above = CoordinateDiff{3}; - auto data_dilate_strides = Strides{3}; - auto conv = make_shared(param0, - param1, - move_strides, - dilate_strides, - padding_below, - padding_above, - data_dilate_strides); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 285})); - - EXPECT_EQ(conv->get_window_movement_strides(), Strides{1}); - EXPECT_EQ(conv->get_window_dilation_strides(), Strides{2}); - EXPECT_EQ(conv->get_data_dilation_strides(), Strides{3}); - - EXPECT_EQ(conv->get_padding_below(), CoordinateDiff{2}); - EXPECT_EQ(conv->get_padding_above(), CoordinateDiff{3}); -} - -TEST(type_prop, conv_2d_deduce) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 100, 150}); - auto param1 = make_shared(element::f32, Shape{128, 3, 10, 20}); - auto conv = make_shared(param0, param1); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 91, 131})); - - EXPECT_EQ(conv->get_window_movement_strides(), (Strides{1, 1})); - EXPECT_EQ(conv->get_window_dilation_strides(), (Strides{1, 1})); - EXPECT_EQ(conv->get_data_dilation_strides(), (Strides{1, 1})); - - EXPECT_EQ(conv->get_padding_below(), (CoordinateDiff{0, 0})); - EXPECT_EQ(conv->get_padding_above(), (CoordinateDiff{0, 0})); -} - -TEST(type_prop, conv_2d_deduce_padded) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 100, 150}); - auto param1 = make_shared(element::f32, Shape{128, 3, 10, 20}); - auto move_strides = Strides{1, 1}; - auto dilate_strides = Strides{1, 1}; - auto padding_below = CoordinateDiff{2, 3}; - auto padding_above = CoordinateDiff{3, 4}; - auto conv = make_shared( - param0, param1, move_strides, dilate_strides, padding_below, padding_above); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 96, 138})); - - EXPECT_EQ(conv->get_window_movement_strides(), (Strides{1, 1})); - EXPECT_EQ(conv->get_window_dilation_strides(), (Strides{1, 1})); - EXPECT_EQ(conv->get_data_dilation_strides(), (Strides{1, 1})); - - EXPECT_EQ(conv->get_padding_below(), (CoordinateDiff{2, 3})); - EXPECT_EQ(conv->get_padding_above(), (CoordinateDiff{3, 4})); -} - -TEST(type_prop, conv_2d_deduce_padded_neg) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 100, 150}); - auto param1 = make_shared(element::f32, Shape{128, 3, 10, 20}); - auto move_strides = Strides{1, 1}; - auto dilate_strides = Strides{1, 1}; - auto padding_below = CoordinateDiff{2, -3}; - auto padding_above = CoordinateDiff{3, -4}; - auto conv = make_shared( - param0, param1, move_strides, dilate_strides, padding_below, padding_above); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 96, 124})); - - EXPECT_EQ(conv->get_window_movement_strides(), (Strides{1, 1})); - EXPECT_EQ(conv->get_window_dilation_strides(), (Strides{1, 1})); - EXPECT_EQ(conv->get_data_dilation_strides(), (Strides{1, 1})); - - EXPECT_EQ(conv->get_padding_below(), (CoordinateDiff{2, -3})); - EXPECT_EQ(conv->get_padding_above(), (CoordinateDiff{3, -4})); -} - -struct DeduceAutoPadTest - : ::testing::TestWithParam< - std::tuple> -{ -}; - -TEST_P(DeduceAutoPadTest, same_lower) -{ - auto image_shape = std::get<0>(GetParam()); - image_shape.insert(image_shape.begin(), {1, 1}); // Add {N, C} - auto filter_shape = std::get<1>(GetParam()); - filter_shape.insert(filter_shape.begin(), {1, 1}); // Add {O, I} - auto param0 = make_shared(element::f32, image_shape); - auto param1 = make_shared(element::f32, filter_shape); - - auto conv = make_shared(param0, - param1, - std::get<2>(GetParam()), - std::get<3>(GetParam()), - CoordinateDiff(), - CoordinateDiff(), - Strides(), - op::PadType::SAME_LOWER); - EXPECT_EQ(conv->get_padding_above(), std::get<4>(GetParam())); - EXPECT_EQ(conv->get_padding_below(), std::get<5>(GetParam())); -} - -INSTANTIATE_TEST_SUITE_P(type_prop, - DeduceAutoPadTest, - ::testing::Values(std::make_tuple(Shape{5, 6}, - Shape{3, 4}, - Strides{2, 1}, - Strides{1, 1}, - CoordinateDiff{1, 1}, - CoordinateDiff{1, 2}), - std::make_tuple(Shape{3, 3}, - Shape{2, 2}, - Strides{1, 1}, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}), - std::make_tuple(Shape{28, 28}, - Shape{3, 3}, - Strides{2, 2}, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}), - std::make_tuple(Shape{100, 150}, - Shape{10, 20}, - Strides{1, 1}, - Strides{1, 1}, - CoordinateDiff{4, 9}, - CoordinateDiff{5, 10}), - std::make_tuple(Shape{2}, - Shape{1}, - Strides{3}, - Strides{1}, - CoordinateDiff{0}, - CoordinateDiff{0}), - std::make_tuple(Shape{10, 1}, - Shape{4, 1}, - Strides{1, 1}, - Strides{2, 1}, - CoordinateDiff{3, 0}, - CoordinateDiff{3, 0}), - std::make_tuple(Shape{10, 5, 6}, - Shape{3, 3, 4}, - Strides{1, 2, 1}, - Strides{2, 1, 1}, - CoordinateDiff{2, 1, 1}, - CoordinateDiff{2, 1, 2}))); - -TEST(type_prop, conv_2d_deduce_strided) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 100, 150}); - auto param1 = make_shared(element::f32, Shape{128, 3, 10, 20}); - auto move_strides = Strides{2, 3}; - auto conv = make_shared(param0, param1, move_strides); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 46, 44})); - - EXPECT_EQ(conv->get_window_movement_strides(), (Strides{2, 3})); - EXPECT_EQ(conv->get_window_dilation_strides(), (Strides{1, 1})); - EXPECT_EQ(conv->get_data_dilation_strides(), (Strides{1, 1})); - - EXPECT_EQ(conv->get_padding_below(), (CoordinateDiff{0, 0})); - EXPECT_EQ(conv->get_padding_above(), (CoordinateDiff{0, 0})); -} - -TEST(type_prop, conv_2d_deduce_strided_window_dilated) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 100, 150}); - auto param1 = make_shared(element::f32, Shape{128, 3, 10, 20}); - auto move_strides = Strides{2, 3}; - auto dilate_strides = Strides{3, 2}; - auto conv = make_shared(param0, param1, move_strides, dilate_strides); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 37, 38})); - - EXPECT_EQ(conv->get_window_movement_strides(), (Strides{2, 3})); - EXPECT_EQ(conv->get_window_dilation_strides(), (Strides{3, 2})); - EXPECT_EQ(conv->get_data_dilation_strides(), (Strides{1, 1})); - - EXPECT_EQ(conv->get_padding_below(), (CoordinateDiff{0, 0})); - EXPECT_EQ(conv->get_padding_above(), (CoordinateDiff{0, 0})); -} - -TEST(type_prop, conv_2d_deduce_strided_window_dilated_data_dilated) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 100, 150}); - auto param1 = make_shared(element::f32, Shape{128, 3, 10, 20}); - auto move_strides = Strides{2, 3}; - auto dilate_strides = Strides{3, 2}; - auto padding_below = CoordinateDiff{0, 0}; - auto padding_above = CoordinateDiff{0, 0}; - auto data_dilate_strides = Strides{2, 3}; - auto conv = make_shared(param0, - param1, - move_strides, - dilate_strides, - padding_below, - padding_above, - data_dilate_strides); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 86, 137})); - - EXPECT_EQ(conv->get_window_movement_strides(), (Strides{2, 3})); - EXPECT_EQ(conv->get_window_dilation_strides(), (Strides{3, 2})); - EXPECT_EQ(conv->get_data_dilation_strides(), (Strides{2, 3})); - - EXPECT_EQ(conv->get_padding_below(), (CoordinateDiff{0, 0})); - EXPECT_EQ(conv->get_padding_above(), (CoordinateDiff{0, 0})); -} - -TEST(type_prop, conv_2d_deduce_strided_window_dilated_small) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 7, 8}); - auto param1 = make_shared(element::f32, Shape{128, 3, 2, 3}); - auto move_strides = Strides{2, 3}; - auto dilate_strides = Strides{3, 2}; - auto conv = make_shared(param0, param1, move_strides, dilate_strides); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 2, 2})); - - EXPECT_EQ(conv->get_window_movement_strides(), (Strides{2, 3})); - EXPECT_EQ(conv->get_window_dilation_strides(), (Strides{3, 2})); - EXPECT_EQ(conv->get_data_dilation_strides(), (Strides{1, 1})); - - EXPECT_EQ(conv->get_padding_below(), (CoordinateDiff{0, 0})); - EXPECT_EQ(conv->get_padding_above(), (CoordinateDiff{0, 0})); -} - -TEST(type_prop, conv_3d_deduce_strided_window_dilated_small) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 7, 8, 10}); - auto param1 = make_shared(element::f32, Shape{128, 3, 2, 3, 2}); - auto move_strides = Strides{2, 3, 4}; - auto dilate_strides = Strides{3, 2, 2}; - auto conv = make_shared(param0, param1, move_strides, dilate_strides); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 2, 2, 2})); - - EXPECT_EQ(conv->get_window_movement_strides(), (Strides{2, 3, 4})); - EXPECT_EQ(conv->get_window_dilation_strides(), (Strides{3, 2, 2})); - EXPECT_EQ(conv->get_data_dilation_strides(), (Strides{1, 1, 1})); - - EXPECT_EQ(conv->get_padding_below(), (CoordinateDiff{0, 0, 0})); - EXPECT_EQ(conv->get_padding_above(), (CoordinateDiff{0, 0, 0})); -} - -TEST(type_prop, conv_3d_deduce_strided_window_dilated_data_dilated_small) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{64, 3, 7, 8, 10}); - auto param1 = make_shared(element::f32, Shape{128, 3, 2, 3, 2}); - auto move_strides = Strides{2, 3, 4}; - auto dilate_strides = Strides{3, 2, 2}; - auto padding_below = CoordinateDiff{0, 0, 0}; - auto padding_above = CoordinateDiff{0, 0, 0}; - auto data_dilate_strides = Strides{2, 3, 2}; - auto conv = make_shared(param0, - param1, - move_strides, - dilate_strides, - padding_below, - padding_above, - data_dilate_strides); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), (Shape{64, 128, 5, 6, 5})); - - EXPECT_EQ(conv->get_window_movement_strides(), (Strides{2, 3, 4})); - EXPECT_EQ(conv->get_window_dilation_strides(), (Strides{3, 2, 2})); - EXPECT_EQ(conv->get_data_dilation_strides(), (Strides{2, 3, 2})); - - EXPECT_EQ(conv->get_padding_below(), (CoordinateDiff{0, 0, 0})); - EXPECT_EQ(conv->get_padding_above(), (CoordinateDiff{0, 0, 0})); -} - -TEST(type_prop, conv_invalid_element_type_mismatch) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{3, 3, 3, 3}); - auto param1 = make_shared(element::i32, Shape{3, 3, 2, 2}); - try - { - auto conv = make_shared(param0, param1); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with element type mismatch not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Element types for data batch and filters do not match")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_0d_input) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{}); - auto param1 = make_shared(element::f32, Shape{}); - try - { - auto conv = make_shared(param0, param1); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid 0D input not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Data batch and filters must have rank of at least 3 " - "(one batch axis, one input-channel axis, " - "and at least one spatial dimension)")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_1d_input) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{2}); - auto param1 = make_shared(element::f32, Shape{2}); - try - { - auto conv = make_shared(param0, param1); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid 1D input not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Data batch and filters must have rank of at least 3 " - "(one batch axis, one input-channel axis, " - "and at least one spatial dimension)")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_2d_input) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{2, 6}); - auto param1 = make_shared(element::f32, Shape{2, 6}); - try - { - auto conv = make_shared(param0, param1); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid 2D input not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Data batch and filters must have rank of at least 3 " - "(one batch axis, one input-channel axis, " - "and at least one spatial dimension)")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_0_batch_size) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{0, 6, 1}); - auto param1 = make_shared(element::f32, Shape{0, 6, 1}); - try - { - auto conv = make_shared(param0, param1); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with 0 batch size not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), std::string("Batch size is zero")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_0_input_channels) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 0, 1}); - auto param1 = make_shared(element::f32, Shape{5, 0, 1}); - try - { - auto conv = make_shared(param0, param1); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with 0 input channels not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Data batch channel count and/or filter input channel count is zero")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_wrong_number_of_filter_dimensions_too_many) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{5, 2, 3, 3, 3}); - try - { - auto conv = make_shared(param0, param1); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with too many filter dimensions not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), std::string("Data batch and filters rank do not match")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_wrong_number_of_filter_dimensions_too_few) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{5, 2, 3}); - try - { - auto conv = make_shared(param0, param1); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with too few filter dimensions not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), std::string("Data batch and filters rank do not match")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_0_output_channels) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{0, 2, 3, 3}); - try - { - auto conv = make_shared(param0, param1); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with 0 output channels not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), std::string("Filter output channel count is zero")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_input_channel_mismatch) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{6, 3, 3, 3}); - try - { - auto conv = make_shared(param0, param1); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with channel count mismatch not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string( - "Data batch channel count (2) does not match filter input channel count (3)")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_movement_stride_rank) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{6, 2, 3, 3}); - try - { - auto conv = make_shared(param0, param1, Strides{2, 3, 8}); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with wrong movement stride rank not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Ranks for data item shape/filters shape (data batch has shape " - "{6,2,10,10}, so data item rank is 2 and filters have shape {6,2,3,3}, so " - "filters spatial rank is 2), data dilation (Strides{1, 1}), padding below " - "(CoordinateDiff{0, 0}), padding above (CoordinateDiff{0, 0}), filter " - "strides (Strides{2, 3, 8}), and filter dilation (Strides{1, 1}) do not " - "match")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_window_dilation_stride_rank) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{6, 2, 3, 3}); - try - { - auto conv = - make_shared(param0, param1, Strides{2, 3}, Strides{2, 3, 8}); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with wrong window dilation stride rank not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Ranks for data item shape/filters shape (data batch has shape " - "{6,2,10,10}, so data item rank is 2 and filters have shape {6,2,3,3}, so " - "filters spatial rank is 2), data dilation (Strides{1, 1}), padding below " - "(CoordinateDiff{0, 0}), padding above (CoordinateDiff{0, 0}), filter " - "strides (Strides{2, 3}), and filter dilation (Strides{2, 3, 8}) do not " - "match")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_data_dilation_stride_rank) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{6, 2, 3, 3}); - try - { - auto conv = make_shared(param0, - param1, - Strides{2, 3}, - Strides{2, 3}, - CoordinateDiff{0, 0}, - CoordinateDiff{0, 0}, - Strides{2, 3, 8}); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with wrong data dilation stride rank not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Ranks for data item shape/filters shape (data batch has shape " - "{6,2,10,10}, so data item rank is 2 and filters have shape {6,2,3,3}, so " - "filters spatial rank is 2), data dilation (Strides{2, 3, 8}), padding " - "below (CoordinateDiff{0, 0}), padding above (CoordinateDiff{0, 0}), " - "filter strides (Strides{2, 3}), and filter dilation (Strides{2, 3}) do " - "not match")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_padding_below_rank) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{6, 2, 3, 3}); - try - { - auto conv = make_shared(param0, - param1, - Strides{2, 3}, - Strides{1, 1}, - CoordinateDiff{0, 0, 0}, - CoordinateDiff{0, 0}); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with wrong padding-below rank not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string( - "Ranks for data item shape/filters shape (data batch has shape " - "{6,2,10,10}, so data item rank is 2 and filters have shape {6,2,3,3}, so " - "filters spatial rank is 2), data dilation (Strides{1, 1}), padding below " - "(CoordinateDiff{0, 0, 0}), padding above (CoordinateDiff{0, 0}), filter " - "strides (Strides{2, 3}), and filter dilation (Strides{1, 1}) do not match")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_padding_above_rank) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{6, 2, 3, 3}); - try - { - auto conv = make_shared(param0, - param1, - Strides{2, 3}, - Strides{2, 3}, - CoordinateDiff{0, 0}, - CoordinateDiff{0, 0, 0}); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with wrong padding-above rank not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string( - "Ranks for data item shape/filters shape (data batch has shape " - "{6,2,10,10}, so data item rank is 2 and filters have shape {6,2,3,3}, so " - "filters spatial rank is 2), data dilation (Strides{1, 1}), padding below " - "(CoordinateDiff{0, 0}), padding above (CoordinateDiff{0, 0, 0}), filter " - "strides (Strides{2, 3}), and filter dilation (Strides{2, 3}) do not match")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_input_spatial_size_negative_after_padding) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{6, 2, 3, 3}); - try - { - auto conv = make_shared(param0, - param1, - Strides{1, 1}, - Strides{1, 1}, - CoordinateDiff{-4, 0}, - CoordinateDiff{-7, 0}); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with negative-length post-padding spatial axis not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Data shape after padding and dilation has dimension less " - "than 1 (dim: -1) at axis 0")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_input_spatial_size_zero_after_padding) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{6, 2, 3, 3}); - try - { - auto conv = make_shared(param0, - param1, - Strides{1, 1}, - Strides{1, 1}, - CoordinateDiff{-4, 0}, - CoordinateDiff{-6, 0}); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with zero-length post-padding spatial axis not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Data shape after padding and dilation has dimension less " - "than 1 (dim: 0) at axis 0")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_input_spatial_size_0) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 0, 10}); - auto param1 = make_shared(element::f32, Shape{6, 2, 3, 3}); - try - { - auto conv = make_shared(param0, param1); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with zero-length spatial axis not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Data shape after padding and dilation has " - "dimension less than 1 (dim: 0) at axis 0")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_window_size_0) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{6, 2, 3, 0}); - try - { - auto conv = make_shared(param0, param1); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with zero-length window axis not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Window after dilation has dimension less than 1 (dim: 0) at axis 1")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_window_dilation_stride_0) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{6, 2, 3, 3}); - try - { - auto conv = make_shared(param0, param1, Strides{2, 3}, Strides{2, 0}); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with wrong 0-length window dilation stride axis not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Window dilation (Strides{2, 0}) has zero dimension at axis 1")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_data_dilation_stride_0) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{6, 2, 3, 3}); - try - { - auto conv = make_shared(param0, - param1, - Strides{2, 3}, - Strides{2, 3}, - CoordinateDiff{0, 0}, - CoordinateDiff{0, 0}, - Strides{2, 0}); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with wrong 0-length data dilation stride axis not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Data dilation (Strides{2, 0}) has zero dimension at axis 1")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_dilated_window_too_large) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 8, 8}); - auto param1 = make_shared(element::f32, Shape{6, 2, 3, 3}); - try - { - auto conv = make_shared(param0, param1, Strides{1, 1}, Strides{4, 4}); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with oversized dilated window not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Window after dilation has dimension (dim: 9) larger than " - "the data shape after padding (dim: 8) at axis 0")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_invalid_movement_stride_0) -{ - // Deduce type - auto param0 = make_shared(element::f32, Shape{6, 2, 10, 10}); - auto param1 = make_shared(element::f32, Shape{6, 2, 3, 3}); - try - { - auto conv = make_shared(param0, param1, Strides{0, 1}); - - // Should have thrown, so fail if it didn't - FAIL() << "Invalid input with wrong 0-length movement stride axis not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Window strides (Strides{0, 1}) has zero dimension at axis 0")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_dynamic_rank_dynamic_ok) -{ - PartialShape data_batch_shape{PartialShape::dynamic()}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_EQ(conv->get_output_element_type(0), element::f32); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme(PartialShape::dynamic(4))); -} - -TEST(type_prop, conv_partial_rank_dynamic_rank_dynamic_window_strides_rank_wrong) -{ - PartialShape data_batch_shape{PartialShape::dynamic()}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Window stride rank mismatch not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Ranks for data item shape/filters shape (data batch has shape ?, so data " - "item rank is ? and filters have shape ?, so filters spatial rank is ?), " - "data dilation (Strides{1, 1}), padding below (CoordinateDiff{0, 0}), " - "padding above (CoordinateDiff{0, 0}), filter strides (Strides{1, 1, 1}), " - "and filter dilation (Strides{1, 1}) do not match")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_dynamic_rank_dynamic_window_strides_dim_zero) -{ - PartialShape data_batch_shape{PartialShape::dynamic()}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 0}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Window stride with dimension zero not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Window strides (Strides{1, 0}) has zero dimension at axis 1")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_dynamic_rank_dynamic_window_dilation_rank_wrong) -{ - PartialShape data_batch_shape{PartialShape::dynamic()}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Window dilation rank mismatch not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Ranks for data item shape/filters shape (data batch has shape ?, so data " - "item rank is ? and filters have shape ?, so filters spatial rank is ?), " - "data dilation (Strides{1, 1}), padding below (CoordinateDiff{0, 0}), " - "padding above (CoordinateDiff{0, 0}), filter strides (Strides{1, 1}), and " - "filter dilation (Strides{1, 1, 1}) do not match")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_dynamic_rank_dynamic_window_dilation_dim_zero) -{ - PartialShape data_batch_shape{PartialShape::dynamic()}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 0}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Window dilation with dimension zero not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Window dilation (Strides{1, 0}) has zero dimension at axis 1")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_dynamic_rank_dynamic_padding_below_rank_wrong) -{ - PartialShape data_batch_shape{PartialShape::dynamic()}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Padding below rank mismatch not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Ranks for data item shape/filters shape (data batch has shape ?, so data " - "item rank is ? and filters have shape ?, so filters spatial rank is ?), " - "data dilation (Strides{1, 1}), padding below (CoordinateDiff{0, 0, 0}), " - "padding above (CoordinateDiff{0, 0}), filter strides (Strides{1, 1}), and " - "filter dilation (Strides{1, 1}) do not match")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_dynamic_rank_dynamic_padding_above_rank_wrong) -{ - PartialShape data_batch_shape{PartialShape::dynamic()}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Padding above rank mismatch not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Ranks for data item shape/filters shape (data batch has shape ?, so data " - "item rank is ? and filters have shape ?, so filters spatial rank is ?), " - "data dilation (Strides{1, 1}), padding below (CoordinateDiff{0, 0}), " - "padding above (CoordinateDiff{0, 0, 0}), filter strides (Strides{1, 1}), " - "and filter dilation (Strides{1, 1}) do not match")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_dynamic_rank_dynamic_data_dilation_rank_wrong) -{ - PartialShape data_batch_shape{PartialShape::dynamic()}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Data dilation rank mismatch not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Ranks for data item shape/filters shape (data batch has shape ?, so data " - "item rank is ? and filters have shape ?, so filters spatial rank is ?), " - "data dilation (Strides{1, 1, 1}), padding below (CoordinateDiff{0, 0}), " - "padding above (CoordinateDiff{0, 0}), filter strides (Strides{1, 1}), and " - "filter dilation (Strides{1, 1}) do not match")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_dynamic_rank_dynamic_data_dilation_dim_zero) -{ - PartialShape data_batch_shape{PartialShape::dynamic()}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 0}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Data dilation with dimension zero not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Data dilation (Strides{1, 0}) has zero dimension at axis 1")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_static_dynamic_rank_dynamic_ok) -{ - PartialShape data_batch_shape{PartialShape::dynamic(4)}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_EQ(conv->get_output_element_type(0), element::f32); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme(PartialShape::dynamic(4))); -} - -TEST(type_prop, conv_partial_rank_static_dynamic_rank_dynamic_data_batch_rank_wrong) -{ - PartialShape data_batch_shape{PartialShape::dynamic(5)}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Data batch rank mismatch not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Ranks for data item shape/filters shape (data batch has shape " - "{?,?,?,?,?}, so data item rank is 3 and filters have shape ?, so filters " - "spatial rank is ?), data dilation (Strides{1, 1}), padding below " - "(CoordinateDiff{0, 0}), padding above (CoordinateDiff{0, 0}), filter " - "strides (Strides{1, 1}), and filter dilation (Strides{1, 1}) do not " - "match")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_static_dynamic_rank_dynamic_batch_size_known_ok) -{ - PartialShape data_batch_shape{ - 64, Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_EQ(conv->get_output_element_type(0), element::f32); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme( - PartialShape{64, Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()})); -} - -TEST(type_prop, conv_partial_rank_static_dynamic_rank_dynamic_batch_size_known_zero) -{ - PartialShape data_batch_shape{ - 0, Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Zero batch size not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), std::string("Batch size is zero")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_static_dynamic_rank_dynamic_input_channel_count_known_ok) -{ - PartialShape data_batch_shape{ - Dimension::dynamic(), 3, Dimension::dynamic(), Dimension::dynamic()}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_EQ(conv->get_output_element_type(0), element::f32); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme(PartialShape::dynamic(4))); -} - -TEST(type_prop, conv_partial_rank_static_dynamic_rank_dynamic_input_channel_count_known_zero) -{ - PartialShape data_batch_shape{ - Dimension::dynamic(), 0, Dimension::dynamic(), Dimension::dynamic()}; - PartialShape filters_shape{PartialShape::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Zero input channel count not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Data batch channel count and/or filter input channel count is zero")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_dynamic_rank_static_dynamic_output_channel_count_known_ok) -{ - PartialShape data_batch_shape{PartialShape::dynamic(4)}; - PartialShape filters_shape{ - 32, Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_EQ(conv->get_output_element_type(0), element::f32); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme( - PartialShape{Dimension::dynamic(), 32, Dimension::dynamic(), Dimension::dynamic()})); -} - -TEST(type_prop, conv_partial_rank_dynamic_rank_static_dynamic_output_channel_count_known_zero) -{ - PartialShape data_batch_shape{PartialShape::dynamic(4)}; - PartialShape filters_shape{0, Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Zero output channel count not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), std::string("Filter output channel count is zero")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_dynamic_rank_static_dynamic_input_channel_count_known_ok) -{ - PartialShape data_batch_shape{PartialShape::dynamic(4)}; - PartialShape filters_shape{Dimension::dynamic(), 4, Dimension::dynamic(), Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_EQ(conv->get_output_element_type(0), element::f32); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme(PartialShape::dynamic(4))); -} - -TEST(type_prop, conv_partial_rank_dynamic_rank_static_dynamic_input_channel_count_known_zero) -{ - PartialShape data_batch_shape{PartialShape::dynamic(4)}; - PartialShape filters_shape{Dimension::dynamic(), 0, Dimension::dynamic(), Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Zero input channel count not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Data batch channel count and/or filter input channel count is zero")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_static_dynamic_rank_static_dynamic_ok) -{ - PartialShape data_batch_shape{PartialShape::dynamic(4)}; - PartialShape filters_shape{PartialShape::dynamic(4)}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_EQ(conv->get_output_element_type(0), element::f32); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme(PartialShape::dynamic(4))); -} - -TEST(type_prop, conv_partial_rank_static_dynamic_rank_static_dynamic_arg_ranks_mismatch) -{ - PartialShape data_batch_shape{PartialShape::dynamic(5)}; - PartialShape filters_shape{PartialShape::dynamic(4)}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Argument rank mismatch not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Data batch and filters rank do not match (data batch " - "shape: {?,?,?,?,?}, filters shape: {?,?,?,?})")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_static_dynamic_rank_static_dynamic_input_channel_counts_known_ok) -{ - PartialShape data_batch_shape{ - Dimension::dynamic(), 3, Dimension::dynamic(), Dimension::dynamic()}; - PartialShape filters_shape{Dimension::dynamic(), 3, Dimension::dynamic(), Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_EQ(conv->get_output_element_type(0), element::f32); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme(PartialShape::dynamic(4))); -} - -TEST(type_prop, conv_partial_rank_static_dynamic_rank_static_dynamic_input_channel_counts_mismatch) -{ - PartialShape data_batch_shape{ - Dimension::dynamic(), 3, Dimension::dynamic(), Dimension::dynamic()}; - PartialShape filters_shape{ - Dimension::dynamic(), 22, Dimension::dynamic(), Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Input channel count mismatch not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string( - "Data batch channel count (3) does not match filter input channel count (22)")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_rank_static_dynamic_rank_static_dynamic_all_nonspatial_known_ok) -{ - PartialShape data_batch_shape{64, 3, Dimension::dynamic(), Dimension::dynamic()}; - PartialShape filters_shape{100, 3, Dimension::dynamic(), Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_EQ(conv->get_output_element_type(0), element::f32); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme( - PartialShape{64, 100, Dimension::dynamic(), Dimension::dynamic()})); -} - -TEST(type_prop, - conv_partial_rank_static_dynamic_rank_static_dynamic_all_nonspatial_some_spatial_known_ok) -{ - PartialShape data_batch_shape{64, 3, 200, Dimension::dynamic()}; - PartialShape filters_shape{100, 3, 5, Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_EQ(conv->get_output_element_type(0), element::f32); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme( - PartialShape{64, 100, 196, Dimension::dynamic()})); -} - -TEST( - type_prop, - conv_partial_rank_static_dynamic_rank_static_dynamic_all_nonspatial_some_spatial_known_filters_too_big) -{ - PartialShape data_batch_shape{64, 3, 200, Dimension::dynamic()}; - PartialShape filters_shape{100, 3, 201, Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Oversize filter not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Window after dilation has dimension (dim: 201) larger " - "than the data shape after padding (dim: 200) at axis 0")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST( - type_prop, - conv_partial_rank_static_dynamic_rank_static_dynamic_all_nonspatial_some_spatial_known_filters_not_too_big_after_padding) -{ - PartialShape data_batch_shape{64, 3, 200, Dimension::dynamic()}; - PartialShape filters_shape{100, 3, 201, Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{2, 0}; - CoordinateDiff padding_above{-1, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_EQ(conv->get_output_element_type(0), element::f32); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme( - PartialShape{64, 100, 1, Dimension::dynamic()})); -} - -TEST( - type_prop, - conv_partial_rank_static_dynamic_rank_static_dynamic_all_nonspatial_some_spatial_known_filters_not_too_big_after_data_dilation) -{ - PartialShape data_batch_shape{64, 3, 200, Dimension::dynamic()}; - PartialShape filters_shape{100, 3, 201, Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{2, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_EQ(conv->get_output_element_type(0), element::f32); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme( - PartialShape{64, 100, 199, Dimension::dynamic()})); -} - -TEST( - type_prop, - conv_partial_rank_static_dynamic_rank_static_dynamic_all_nonspatial_some_spatial_known_filters_not_too_big_after_data_dilation_strided) -{ - PartialShape data_batch_shape{64, 3, 200, Dimension::dynamic()}; - PartialShape filters_shape{100, 3, 201, Dimension::dynamic()}; - Strides window_movement_strides{3, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{2, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_EQ(conv->get_output_element_type(0), element::f32); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme( - PartialShape{64, 100, 67, Dimension::dynamic()})); -} - -TEST( - type_prop, - conv_partial_rank_static_dynamic_rank_static_dynamic_all_nonspatial_some_spatial_known_filters_too_big_after_filter_dilation) -{ - PartialShape data_batch_shape{64, 3, 200, Dimension::dynamic()}; - PartialShape filters_shape{100, 3, 101, Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{2, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Oversize filter after window dilation not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Window after dilation has dimension (dim: 201) larger " - "than the data shape after padding (dim: 200) at axis 0")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST( - type_prop, - conv_partial_rank_static_dynamic_rank_static_dynamic_all_nonspatial_some_spatial_zero_data_batch_dim) -{ - PartialShape data_batch_shape{64, 3, 200, 0}; - PartialShape filters_shape{100, 3, 5, Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Zero dimension in data batch not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Data shape after padding and dilation has " - "dimension less than 1 (dim: 0) at axis 1")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST( - type_prop, - conv_partial_rank_static_dynamic_rank_static_dynamic_all_nonspatial_some_spatial_positive_data_batch_dim_after_padding) -{ - PartialShape data_batch_shape{64, 3, 200, 0}; - PartialShape filters_shape{100, 3, 5, Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 2}; - CoordinateDiff padding_above{0, -1}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_EQ(conv->get_output_element_type(0), element::f32); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme( - PartialShape{64, 100, 196, Dimension::dynamic()})); -} - -TEST( - type_prop, - conv_partial_rank_static_dynamic_rank_static_dynamic_all_nonspatial_some_spatial_zero_data_batch_dim_after_padding) -{ - PartialShape data_batch_shape{64, 3, 200, 20}; - PartialShape filters_shape{100, 3, 5, Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, 0}; - CoordinateDiff padding_above{0, -20}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Zero padded dimension in data batch not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Data shape after padding and dilation has " - "dimension less than 1 (dim: 0) at axis 1")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST( - type_prop, - conv_partial_rank_static_dynamic_rank_static_dynamic_all_nonspatial_some_spatial_negative_data_batch_dim_after_padding) -{ - PartialShape data_batch_shape{64, 3, 200, 20}; - PartialShape filters_shape{100, 3, 5, Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{0, -1}; - CoordinateDiff padding_above{0, -20}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, filters_shape); - - try - { - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - FAIL() << "Negative padded dimension in data batch not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Data shape after padding and dilation has dimension less " - "than 1 (dim: -1) at axis 1")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, conv_partial_dynamic_et) -{ - // For this test the exact shape parameters are kind of arbitrary---just copied and pasted - // from some known-"OK" test above. We're only concerned about the element types. - PartialShape data_batch_shape{64, 3, 200, Dimension::dynamic()}; - PartialShape filters_shape{100, 3, 201, Dimension::dynamic()}; - Strides window_movement_strides{1, 1}; - Strides window_dilation_strides{1, 1}; - CoordinateDiff padding_below{2, 0}; - CoordinateDiff padding_above{-1, 0}; - Strides data_dilation_strides{1, 1}; - - auto param0 = make_shared(element::dynamic, data_batch_shape); - auto param1 = make_shared(element::dynamic, filters_shape); - - auto conv = make_shared(param0, - param1, - window_movement_strides, - window_dilation_strides, - padding_below, - padding_above, - data_dilation_strides); - - ASSERT_TRUE(conv->get_output_element_type(0).is_dynamic()); - ASSERT_TRUE(conv->get_output_partial_shape(0).same_scheme( - PartialShape{64, 100, 1, Dimension::dynamic()})); -} - TEST(type_prop, conv_v1_partial_rank) { PartialShape data_batch_shape{PartialShape::dynamic()}; diff --git a/ngraph/test/type_prop/convolution_backprop_data.cpp b/ngraph/test/type_prop/convolution_backprop_data.cpp index 3dfac03a1cb..338044bcc98 100644 --- a/ngraph/test/type_prop/convolution_backprop_data.cpp +++ b/ngraph/test/type_prop/convolution_backprop_data.cpp @@ -16,260 +16,11 @@ #include "gtest/gtest.h" #include "ngraph/ngraph.hpp" -#include "op/convolution.hpp" #include "util/type_prop.hpp" using namespace std; using namespace ngraph; -// ---------------------------- v0 ---------------------------- -TEST(type_prop, conv_backprop_data_v0_1d_batch_deduce) -{ - // Deduce type - Shape data_batch_shape{64, 3, 100}; - auto param0 = make_shared(element::f32, Shape{128, 3, 10}); // filters - auto param1 = make_shared(element::f32, Shape{64, 128, 91}); // output delta - auto conv = make_shared(data_batch_shape, - param0, - param1, - Strides{1}, - Strides{1}, - CoordinateDiff{0}, - CoordinateDiff{0}, - Strides{1}); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), data_batch_shape); - - EXPECT_EQ(conv->get_window_movement_strides_forward(), Strides{1}); - EXPECT_EQ(conv->get_window_dilation_strides_forward(), Strides{1}); - EXPECT_EQ(conv->get_data_dilation_strides_forward(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below_forward(), CoordinateDiff{0}); - EXPECT_EQ(conv->get_padding_above_forward(), CoordinateDiff{0}); -} - -TEST(type_prop, conv_backprop_data_v0_1d_batch_deduce_padded) -{ - // Deduce type - Shape data_batch_shape{64, 3, 100}; - auto param0 = make_shared(element::f32, Shape{128, 3, 10}); // filters - auto param1 = make_shared(element::f32, Shape{64, 128, 96}); // output delta - auto move_strides = Strides{1}; - auto dilation_strides = Strides{1}; - auto padding_below = CoordinateDiff{2}; - auto padding_above = CoordinateDiff{3}; - auto conv = make_shared(data_batch_shape, - param0, - param1, - move_strides, - dilation_strides, - padding_below, - padding_above, - Strides{1}); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), data_batch_shape); - - EXPECT_EQ(conv->get_window_movement_strides_forward(), Strides{1}); - EXPECT_EQ(conv->get_window_dilation_strides_forward(), Strides{1}); - EXPECT_EQ(conv->get_data_dilation_strides_forward(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below_forward(), CoordinateDiff{2}); - EXPECT_EQ(conv->get_padding_above_forward(), CoordinateDiff{3}); -} - -TEST(type_prop, conv_backprop_data_v0_1d_batch_deduce_strided) -{ - // Deduce type - Shape data_batch_shape{64, 3, 100}; - auto param0 = make_shared(element::f32, Shape{128, 3, 10}); // filters - auto param1 = make_shared(element::f32, Shape{64, 128, 46}); // output delta - auto move_strides = Strides{2}; - auto conv = make_shared(data_batch_shape, - param0, - param1, - move_strides, - Strides{1}, - CoordinateDiff{0}, - CoordinateDiff{0}, - Strides{1}); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), data_batch_shape); - - EXPECT_EQ(conv->get_window_movement_strides_forward(), Strides{2}); - EXPECT_EQ(conv->get_window_dilation_strides_forward(), Strides{1}); - EXPECT_EQ(conv->get_data_dilation_strides_forward(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below_forward(), CoordinateDiff{0}); - EXPECT_EQ(conv->get_padding_above_forward(), CoordinateDiff{0}); -} - -TEST(type_prop, conv_backprop_data_v0_1d_batch_deduce_strided_padded) -{ - // Deduce type - Shape data_batch_shape{64, 3, 100}; - auto param0 = make_shared(element::f32, Shape{128, 3, 10}); // filters - auto param1 = make_shared(element::f32, Shape{64, 128, 48}); // output delta - auto move_strides = Strides{2}; - auto dilation_strides = Strides{1}; - auto padding_below = CoordinateDiff{2}; - auto padding_above = CoordinateDiff{3}; - auto conv = make_shared(data_batch_shape, - param0, - param1, - move_strides, - dilation_strides, - padding_below, - padding_above, - Strides{1}); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), data_batch_shape); - - EXPECT_EQ(conv->get_window_movement_strides_forward(), Strides{2}); - EXPECT_EQ(conv->get_window_dilation_strides_forward(), Strides{1}); - EXPECT_EQ(conv->get_data_dilation_strides_forward(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below_forward(), CoordinateDiff{2}); - EXPECT_EQ(conv->get_padding_above_forward(), CoordinateDiff{3}); -} - -TEST(type_prop, conv_backprop_data_v0_1d_batch_deduce_strided_small_uneven) -{ - // Deduce type - Shape data_batch_shape{64, 3, 5}; - auto param0 = make_shared(element::f32, Shape{128, 3, 2}); // filters - auto param1 = make_shared(element::f32, Shape{64, 128, 2}); // output delta - auto move_strides = Strides{2}; - auto conv = make_shared(data_batch_shape, - param0, - param1, - move_strides, - Strides{1}, - CoordinateDiff{0}, - CoordinateDiff{0}, - Strides{1}); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), data_batch_shape); - - EXPECT_EQ(conv->get_window_movement_strides_forward(), Strides{2}); - EXPECT_EQ(conv->get_window_dilation_strides_forward(), Strides{1}); - EXPECT_EQ(conv->get_data_dilation_strides_forward(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below_forward(), CoordinateDiff{0}); - EXPECT_EQ(conv->get_padding_above_forward(), CoordinateDiff{0}); -} - -TEST(type_prop, conv_backprop_data_v0_1d_batch_deduce_strided_small_even) -{ - // Deduce type - Shape data_batch_shape{64, 3, 6}; - auto param0 = make_shared(element::f32, Shape{128, 3, 2}); // filters - auto param1 = make_shared(element::f32, Shape{64, 128, 3}); // output delta - auto move_strides = Strides{2}; - auto conv = make_shared(data_batch_shape, - param0, - param1, - move_strides, - Strides{1}, - CoordinateDiff{0}, - CoordinateDiff{0}, - Strides{1}); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), data_batch_shape); - - EXPECT_EQ(conv->get_window_movement_strides_forward(), Strides{2}); - EXPECT_EQ(conv->get_window_dilation_strides_forward(), Strides{1}); - EXPECT_EQ(conv->get_data_dilation_strides_forward(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below_forward(), CoordinateDiff{0}); - EXPECT_EQ(conv->get_padding_above_forward(), CoordinateDiff{0}); -} - -TEST(type_prop, conv_backprop_data_v0_1d_batch_deduce_window_dilated) -{ - // Deduce type - Shape data_batch_shape{64, 3, 100}; - auto param0 = make_shared(element::f32, Shape{128, 3, 10}); // filters - auto param1 = make_shared(element::f32, Shape{64, 128, 82}); // output delta - auto move_strides = Strides{1}; - auto dilate_strides = Strides{2}; - auto conv = make_shared(data_batch_shape, - param0, - param1, - move_strides, - dilate_strides, - CoordinateDiff{0}, - CoordinateDiff{0}, - Strides{1}); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), data_batch_shape); - - EXPECT_EQ(conv->get_window_movement_strides_forward(), Strides{1}); - EXPECT_EQ(conv->get_window_dilation_strides_forward(), Strides{2}); - EXPECT_EQ(conv->get_data_dilation_strides_forward(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below_forward(), CoordinateDiff{0}); - EXPECT_EQ(conv->get_padding_above_forward(), CoordinateDiff{0}); -} - -TEST(type_prop, conv_backprop_data_v0_1d_batch_deduce_window_dilated_padded) -{ - // Deduce type - Shape data_batch_shape{64, 3, 100}; - auto param0 = make_shared(element::f32, Shape{128, 3, 10}); // filters - auto param1 = make_shared(element::f32, Shape{64, 128, 87}); // output delta - auto move_strides = Strides{1}; - auto dilate_strides = Strides{2}; - auto padding_below = CoordinateDiff{2}; - auto padding_above = CoordinateDiff{3}; - auto conv = make_shared(data_batch_shape, - param0, - param1, - move_strides, - dilate_strides, - padding_below, - padding_above, - Strides{1}); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), data_batch_shape); - - EXPECT_EQ(conv->get_window_movement_strides_forward(), Strides{1}); - EXPECT_EQ(conv->get_window_dilation_strides_forward(), Strides{2}); - EXPECT_EQ(conv->get_data_dilation_strides_forward(), Strides{1}); - - EXPECT_EQ(conv->get_padding_below_forward(), CoordinateDiff{2}); - EXPECT_EQ(conv->get_padding_above_forward(), CoordinateDiff{3}); -} - -TEST(type_prop, conv_backprop_data_v0_1d_batch_deduce_window_dilated_data_dilated_padded) -{ - // Deduce type - Shape data_batch_shape{64, 3, 100}; - auto param0 = make_shared(element::f32, Shape{128, 3, 10}); // filters - auto param1 = make_shared(element::f32, Shape{64, 128, 285}); // output delta - auto move_strides = Strides{1}; - auto dilate_strides = Strides{2}; - auto padding_below = CoordinateDiff{2}; - auto padding_above = CoordinateDiff{3}; - auto data_dilate_strides = Strides{3}; - auto conv = make_shared(data_batch_shape, - param0, - param1, - move_strides, - dilate_strides, - padding_below, - padding_above, - data_dilate_strides); - EXPECT_EQ(conv->get_element_type(), element::f32); - EXPECT_EQ(conv->get_shape(), data_batch_shape); - - EXPECT_EQ(conv->get_window_movement_strides_forward(), Strides{1}); - EXPECT_EQ(conv->get_window_dilation_strides_forward(), Strides{2}); - EXPECT_EQ(conv->get_data_dilation_strides_forward(), Strides{3}); - - EXPECT_EQ(conv->get_padding_below_forward(), CoordinateDiff{2}); - EXPECT_EQ(conv->get_padding_above_forward(), CoordinateDiff{3}); -} - // ---------------------------- v1 ---------------------------- TEST(type_prop, convolution_backprop_data_partial_auto_padding_upper) { @@ -338,7 +89,7 @@ TEST(type_prop, convolution_backprop_data_auto_pad_explicit_with_output_padding) auto filters = make_shared(inputs_et, filters_pshape); auto conv_backprop = make_shared( data, filters, strides, padding_begin, padding_end, dilations, auto_pad, output_padding); - + ASSERT_TRUE(conv_backprop->get_output_partial_shape(0).same_scheme(PartialShape{1, 6, 4, 4})); ASSERT_EQ(conv_backprop->get_pads_begin(), (CoordinateDiff{1, 1})); ASSERT_EQ(conv_backprop->get_pads_end(), (CoordinateDiff{1, 1})); @@ -361,9 +112,16 @@ TEST(type_prop, convolution_backprop_data_auto_pad_same_with_output_padding_and_ auto data = make_shared(inputs_et, data_pshape); auto filters = make_shared(inputs_et, filters_pshape); auto output_shape = op::Constant::create(element::i64, Shape{2}, {3, 3}); - auto conv_backprop = make_shared( - data, filters, output_shape, strides, padding_begin, padding_end, dilations, auto_pad, output_padding); - + auto conv_backprop = make_shared(data, + filters, + output_shape, + strides, + padding_begin, + padding_end, + dilations, + auto_pad, + output_padding); + ASSERT_TRUE(conv_backprop->get_output_partial_shape(0).same_scheme(PartialShape{1, 6, 3, 3})); ASSERT_EQ(conv_backprop->get_pads_begin(), (CoordinateDiff{1, 1})); ASSERT_EQ(conv_backprop->get_pads_end(), (CoordinateDiff{2, 2})); @@ -807,13 +565,15 @@ TEST(type_prop, convolution_backprop_data_invalid_et_inputs) // output shape input element type must be of integer type FAIL() << "Invalid element type of output_shape input not detected"; } - catch(const NodeValidationFailure& error) + catch (const NodeValidationFailure& error) { - EXPECT_HAS_SUBSTRING(error.what(), "Element type for output shape should be of integer type"); + EXPECT_HAS_SUBSTRING(error.what(), + "Element type for output shape should be of integer type"); } catch (...) { - FAIL() << "Element type of output_shape input validation check failed for unexpected reason"; + FAIL() + << "Element type of output_shape input validation check failed for unexpected reason"; } } @@ -899,9 +659,8 @@ TEST(type_prop, convolution_backprop_data_invalid_input_ranks) } catch (const NodeValidationFailure& error) { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Spatial shape of output input must be of rank 1")); + EXPECT_HAS_SUBSTRING(error.what(), + std::string("Spatial shape of output input must be of rank 1")); } catch (...) { @@ -930,7 +689,9 @@ TEST(type_prop, convolution_backprop_data_invalid_input_channel_dims) } catch (const NodeValidationFailure& error) { - EXPECT_HAS_SUBSTRING(error.what(), std::string("Input channels dimension of data and filters inputs must be equal")); + EXPECT_HAS_SUBSTRING( + error.what(), + std::string("Input channels dimension of data and filters inputs must be equal")); } catch (...) { @@ -1159,4 +920,4 @@ TEST(type_prop, convolution_backprop_data_invalid_conv_param_spatial_dims) { FAIL() << "Output padding spatial dimensions validation check failed for unexpected reason"; } -} \ No newline at end of file +} diff --git a/ngraph/test/util/engine/ie_engines.cpp b/ngraph/test/util/engine/ie_engines.cpp index 8e1a8f4e75e..ce5e4247b8f 100644 --- a/ngraph/test/util/engine/ie_engines.cpp +++ b/ngraph/test/util/engine/ie_engines.cpp @@ -6,7 +6,6 @@ #include "ngraph/opsets/opset.hpp" #include "ngraph/pass/manager.hpp" -#include "pass/opset1_upgrade.hpp" #include "shared_utils.hpp" using namespace ngraph; @@ -178,7 +177,6 @@ namespace test::IE_Engine::IE_Engine(const std::shared_ptr function, const char* device) : m_function{function} { - upgrade_and_validate_function(m_function); const auto cnn_network = InferenceEngine::CNNNetwork(m_function); m_network_inputs = cnn_network.getInputsInfo(); m_network_outputs = cnn_network.getOutputsInfo(); @@ -200,7 +198,7 @@ void test::IE_Engine::infer() if (m_network_inputs.size() != m_allocated_inputs) { IE_THROW() << "The tested graph has " << m_network_inputs.size() << " inputs, but " - << m_allocated_inputs << " were passed."; + << m_allocated_inputs << " were passed."; } else { @@ -294,26 +292,6 @@ testing::AssertionResult return comparison_result; } -std::shared_ptr - test::IE_Engine::upgrade_and_validate_function(const std::shared_ptr function) const -{ - pass::Manager passes; - passes.register_pass(); - passes.run_passes(function); - - static std::set ie_ops = get_ie_ops(); - for (const auto& node : function->get_ops()) - { - if (ie_ops.find(node->get_type_info()) == ie_ops.end()) - { - IE_THROW() << "Unsupported operator detected in the graph: " - << node->get_type_info().name; - } - } - - return function; -} - std::set test::IE_Engine::get_ie_ops() const { std::set ie_ops = get_opset1().get_type_info_set(); @@ -341,8 +319,8 @@ void test::IE_Engine::reset() namespace InferenceEngine { -// Without this section the linker is not able to find destructors for missing TBlob specializations -// which are instantiated in the unit tests that use TestCase and this engine + // Without this section the linker is not able to find destructors for missing TBlob + // specializations which are instantiated in the unit tests that use TestCase and this engine template TBlob::~TBlob() { diff --git a/ngraph/test/util/engine/ie_engines.hpp b/ngraph/test/util/engine/ie_engines.hpp index 4bcc5de195e..5e219c6351a 100644 --- a/ngraph/test/util/engine/ie_engines.hpp +++ b/ngraph/test/util/engine/ie_engines.hpp @@ -113,11 +113,6 @@ namespace ngraph unsigned int m_allocated_inputs = 0; unsigned int m_allocated_expected_outputs = 0; - /// Upgrades functions containing legacy opset0 to opset1 - /// and checks if the graph can be executed - std::shared_ptr - upgrade_and_validate_function(const std::shared_ptr function) const; - /// Retrieves a set of all ops IE can execute std::set get_ie_ops() const; @@ -160,5 +155,5 @@ namespace ngraph { static constexpr bool value = true; }; - } -} + } // namespace test +} // namespace ngraph From baef88c8fbd37cd4b9cb1232bc4f0d1f77e2ca63 Mon Sep 17 00:00:00 2001 From: Szymon Durawa Date: Thu, 8 Jul 2021 08:03:59 +0200 Subject: [PATCH 05/13] Cosh revise. (#6516) --- docs/ops/arithmetic/Cosh_1.md | 36 +++++++++---------- .../layer_tests_summary/utils/constants.py | 1 + ngraph/core/include/ngraph/op/cosh.hpp | 4 +-- .../include/ngraph/runtime/reference/cosh.hpp | 13 ++++++- ngraph/core/src/op/cosh.cpp | 7 ++-- ngraph/test/CMakeLists.txt | 2 ++ ngraph/test/backend/cosh.in.cpp | 32 ++++++++--------- ngraph/test/type_prop/cosh.cpp | 9 +++++ ngraph/test/visitors/op/cosh.cpp | 11 ++++++ 9 files changed, 71 insertions(+), 44 deletions(-) create mode 100644 ngraph/test/type_prop/cosh.cpp create mode 100644 ngraph/test/visitors/op/cosh.cpp diff --git a/docs/ops/arithmetic/Cosh_1.md b/docs/ops/arithmetic/Cosh_1.md index 08b3be9f421..7f1e3055dd3 100644 --- a/docs/ops/arithmetic/Cosh_1.md +++ b/docs/ops/arithmetic/Cosh_1.md @@ -4,33 +4,29 @@ **Category**: Arithmetic unary operation -**Short description**: *Cosh* performs element-wise hyperbolic cosine operation with given tensor. +**Short description**: *Cosh* performs element-wise hyperbolic cosine operation on a given input tensor. -**Attributes**: - - No attributes available. - -**Inputs** - -* **1**: An tensor of type *T*. **Required.** - -**Outputs** - -* **1**: The result of element-wise cosh operation. A tensor of type *T*. - -**Types** - -* *T*: any numeric type. - -*Cosh* does the following with the input tensor *a*: +**Detailed description**: *Cosh* performs element-wise hyperbolic cosine (cosh) operation on a given input tensor, based on the following mathematical formula: \f[ a_{i} = cosh(a_{i}) \f] -**Examples** +**Attributes**: *Cosh* operation has no attributes. -*Example 1* +**Inputs** + +* **1**: A tensor of type *T* and arbitrary shape. **Required.** + +**Outputs** + +* **1**: The result of element-wise *Cosh* operation. A tensor of type *T* and the same shape as the input tensor. + +**Types** + +* *T*: any numeric type. + +**Example** ```xml diff --git a/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py b/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py index cf562e5ead7..3241dfd7013 100644 --- a/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py +++ b/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py @@ -24,6 +24,7 @@ VERIFIED_OP_REFERENCES = [ 'Convolution-1', 'Constant-1', 'Cos-1', + 'Cosh-1', 'DeformableConvolution-1', 'DeformablePSROIPooling-1', 'DetectionOutput-1', diff --git a/ngraph/core/include/ngraph/op/cosh.hpp b/ngraph/core/include/ngraph/op/cosh.hpp index 7e52bf1679f..6fcf30e8a08 100644 --- a/ngraph/core/include/ngraph/op/cosh.hpp +++ b/ngraph/core/include/ngraph/op/cosh.hpp @@ -16,8 +16,8 @@ namespace ngraph class NGRAPH_API Cosh : public util::UnaryElementwiseArithmetic { public: - static constexpr NodeTypeInfo type_info{"Cosh", 0}; - const NodeTypeInfo& get_type_info() const override { return type_info; } + NGRAPH_RTTI_DECLARATION; + /// \brief Constructs a hyperbolic cosine operation. Cosh() = default; /// \brief Constructs a hyperbolic cosine operation. diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/cosh.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/cosh.hpp index 2529f9a8893..a9a7e17982f 100644 --- a/ngraph/core/reference/include/ngraph/runtime/reference/cosh.hpp +++ b/ngraph/core/reference/include/ngraph/runtime/reference/cosh.hpp @@ -13,7 +13,8 @@ namespace ngraph { namespace reference { - template + template ::value, bool>::type = true> void cosh(const T* arg, T* out, size_t count) { for (size_t i = 0; i < count; i++) @@ -21,6 +22,16 @@ namespace ngraph out[i] = std::cosh(arg[i]); } } + + template ::value, bool>::type = true> + void cosh(const T* arg, T* out, size_t count) + { + for (size_t i = 0; i < count; i++) + { + out[i] = std::roundl(std::cosh(arg[i])); + } + } } // namespace reference } // namespace runtime } // namespace ngraph diff --git a/ngraph/core/src/op/cosh.cpp b/ngraph/core/src/op/cosh.cpp index d4f22bc6f46..3a8d169a67f 100644 --- a/ngraph/core/src/op/cosh.cpp +++ b/ngraph/core/src/op/cosh.cpp @@ -5,16 +5,16 @@ #include "itt.hpp" #include "ngraph/op/cosh.hpp" -#include "ngraph/op/multiply.hpp" -#include "ngraph/op/sinh.hpp" #include "ngraph/runtime/host_tensor.hpp" #include "ngraph/runtime/reference/cosh.hpp" +#include "ngraph/validation_util.hpp" + using namespace std; using namespace ngraph; -constexpr NodeTypeInfo op::Cosh::type_info; +NGRAPH_RTTI_DEFINITION(op::v0::Cosh, "Cosh", 0, util::UnaryElementwiseArithmetic); op::Cosh::Cosh(const Output& arg) : UnaryElementwiseArithmetic(arg) @@ -68,6 +68,7 @@ namespace coshop bool op::Cosh::evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const { NGRAPH_OP_SCOPE(v0_Cosh_evaluate); + NGRAPH_CHECK(validate_host_tensor_vector(outputs, 1) && validate_host_tensor_vector(inputs, 1)); return coshop::evaluate_cosh(inputs[0], outputs[0], shape_size(get_output_shape(0))); } diff --git a/ngraph/test/CMakeLists.txt b/ngraph/test/CMakeLists.txt index 9d608f986e9..8dbf0f888bc 100644 --- a/ngraph/test/CMakeLists.txt +++ b/ngraph/test/CMakeLists.txt @@ -110,6 +110,7 @@ set(SRC type_prop/convolution.cpp type_prop/convolution_backprop_data.cpp type_prop/cos.cpp + type_prop/cosh.cpp type_prop/ctc_greedy_decoder.cpp type_prop/ctc_greedy_decoder_seq_len.cpp type_prop/ctc_loss.cpp @@ -240,6 +241,7 @@ set(SRC visitors/op/convert.cpp visitors/op/convolution_backprop.cpp visitors/op/cos.cpp + visitors/op/cosh.cpp visitors/op/cum_sum.cpp visitors/op/deformable_convolution.cpp visitors/op/deformable_psroi_pooling.cpp diff --git a/ngraph/test/backend/cosh.in.cpp b/ngraph/test/backend/cosh.in.cpp index 1877b50e6be..f0711c5f48f 100644 --- a/ngraph/test/backend/cosh.in.cpp +++ b/ngraph/test/backend/cosh.in.cpp @@ -2,23 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 // -#include -#include -#include -#include -#include -#include - -// clang-format off -#ifdef ${BACKEND_NAME}_FLOAT_TOLERANCE_BITS -#define DEFAULT_FLOAT_TOLERANCE_BITS ${BACKEND_NAME}_FLOAT_TOLERANCE_BITS -#endif - -#ifdef ${BACKEND_NAME}_DOUBLE_TOLERANCE_BITS -#define DEFAULT_DOUBLE_TOLERANCE_BITS ${BACKEND_NAME}_DOUBLE_TOLERANCE_BITS -#endif -// clang-format on - #include "gtest/gtest.h" #include "ngraph/ngraph.hpp" #include "util/engine/test_engines.hpp" @@ -31,7 +14,7 @@ using namespace ngraph; static string s_manifest = "${MANIFEST}"; using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME}); -NGRAPH_TEST(${BACKEND_NAME}, cosh) +NGRAPH_TEST(${BACKEND_NAME}, cosh_float) { Shape shape{6}; auto A = make_shared(element::f32, shape); @@ -49,3 +32,16 @@ NGRAPH_TEST(${BACKEND_NAME}, cosh) test_case.add_expected_output(shape, expected); test_case.run(); } + +NGRAPH_TEST(${BACKEND_NAME}, cosh_int) +{ + Shape shape{5}; + auto A = make_shared(element::i32, shape); + auto f = make_shared(make_shared(A), ParameterVector{A}); + + auto test_case = test::TestCase(f); + test_case.add_input({1, 5, 2, 3, 3}); + test_case.add_expected_output(shape, + {2, 74, 4, 10, 10}); + test_case.run(); +} diff --git a/ngraph/test/type_prop/cosh.cpp b/ngraph/test/type_prop/cosh.cpp new file mode 100644 index 00000000000..6db9dababb3 --- /dev/null +++ b/ngraph/test/type_prop/cosh.cpp @@ -0,0 +1,9 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "unary_ops.hpp" + +using Type = ::testing::Types; + +INSTANTIATE_TYPED_TEST_SUITE_P(type_prop_cosh, UnaryOperator, Type); diff --git a/ngraph/test/visitors/op/cosh.cpp b/ngraph/test/visitors/op/cosh.cpp new file mode 100644 index 00000000000..d44b7701eb3 --- /dev/null +++ b/ngraph/test/visitors/op/cosh.cpp @@ -0,0 +1,11 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "unary_ops.hpp" +using Type = ::testing::Types>; + +INSTANTIATE_TYPED_TEST_SUITE_P(visitor_without_attribute, + UnaryOperatorVisitor, + Type, + UnaryOperatorTypeName); From afe60b3263c0335e414fc31e54e1d868af79e051 Mon Sep 17 00:00:00 2001 From: Szymon Irzabek Date: Thu, 8 Jul 2021 10:49:07 +0200 Subject: [PATCH 06/13] Gna padding tests (#6541) * [GNA] Use built in ngraph padding calculation * [GNA] Use less channels for tests * [GNA] Rename tests file * [GNA] Add ngraph reference tests and some minor fixes in the transformation itself * [GNA] Add invalid ngraph reference tests * [GNA] Align brace style * [GNA] Remove unnecessary condition --- .../convert_padded2valid_conv.cpp | 91 +--- ...conv.cpp => convert_padded2valid_conv.cpp} | 12 +- .../gna_convert_padded2valid_conv.cpp | 453 ++++++++++++++++++ 3 files changed, 462 insertions(+), 94 deletions(-) rename inference-engine/tests/functional/plugin/gna/pass_tests/{padded2valid_conv.cpp => convert_padded2valid_conv.cpp} (98%) create mode 100644 inference-engine/tests/unit/gna/ngraph/transformations/gna_convert_padded2valid_conv.cpp diff --git a/inference-engine/src/gna_plugin/transformations/convert_padded2valid_conv.cpp b/inference-engine/src/gna_plugin/transformations/convert_padded2valid_conv.cpp index 019c7747a5a..b07add2183d 100644 --- a/inference-engine/src/gna_plugin/transformations/convert_padded2valid_conv.cpp +++ b/inference-engine/src/gna_plugin/transformations/convert_padded2valid_conv.cpp @@ -29,19 +29,12 @@ struct ConvData { size_t input_height; size_t input_width; size_t input_channel_count; - size_t filter_height; - size_t filter_width; size_t filter_count; - size_t filter_dilation_width; - size_t filter_dilation_height; - size_t filter_stride_width; - size_t filter_stride_height; size_t pads_begin_width; size_t pads_begin_height; size_t pads_end_width; size_t pads_end_height; ngraph::op::PadType padding_type; - ngraph::Shape output_shape; ngraph::element::Type element_type; }; @@ -55,27 +48,18 @@ static bool VerifyAndGetConvParams(std::shared_ptr return false; } - conv_data.output_shape = conv->get_output_shape(0); conv_data.padding_type = conv->get_auto_pad(); conv_data.input_channel_count = conv->input_value(0).get_shape()[1]; conv_data.input_height = conv->input_value(0).get_shape()[2]; conv_data.input_width = conv->input_value(0).get_shape()[3]; conv_data.filter_count = conv->input_value(1).get_shape()[0]; - conv_data.filter_height = conv->input_value(1).get_shape()[2]; - conv_data.filter_width = conv->input_value(1).get_shape()[3]; - conv_data.filter_dilation_height = conv->get_dilations()[0]; - conv_data.filter_dilation_width = conv->get_dilations()[1]; - conv_data.filter_stride_height = conv->get_strides()[0]; - conv_data.filter_stride_width = conv->get_strides()[1]; conv_data.pads_begin_height = conv->get_pads_begin()[0]; conv_data.pads_begin_width = conv->get_pads_begin()[1]; conv_data.pads_end_height = conv->get_pads_end()[0]; conv_data.pads_end_width = conv->get_pads_end()[1]; conv_data.element_type = conv->get_element_type(); - IE_ASSERT(conv_data.filter_count == conv_data.output_shape[1]); - - return true; + return conv_data.pads_begin_height || conv_data.pads_end_height || conv_data.pads_begin_width || conv_data.pads_end_width; } static bool TransposeOrderMatches(std::shared_ptr transpose, std::vector order) { @@ -117,75 +101,9 @@ static bool VerifyMaxPool(std::shared_ptr max_pool) { auto pool_kernel = max_pool->get_kernel(); // Check if MaxPool vertical stride == pool size - // (TODO: remove when 50386 and 50379 are fixed and also verify pool_kernel[0] > 8 limitation below, gna_limitations can be used then) // Check if padding is VALID return (max_pool->get_auto_pad() == ngraph::op::PadType::VALID && - pool_kernel.size() == 2 && pool_strides.size() == 2 && - pool_kernel[0] == pool_strides[0] && pool_kernel[0] <= 8); -} - -static size_t GetRequiredInputPadding(size_t input_size, size_t filter_size, size_t stride_size, size_t dilation_size, size_t output_size) { - size_t partial_padding_size = (output_size - 1) * stride_size + (filter_size - 1) * dilation_size + 1; - - // This way of padding size calculation avoids problem with fractional numbers - return (partial_padding_size > input_size) ? (partial_padding_size - input_size) : 0; -} - -static size_t CalculateOutputSize(size_t input_size, size_t filter_size, size_t stride_size, size_t dilation_size, size_t padding_size) { - return (input_size + padding_size - ((filter_size - 1) * dilation_size + 1)) / stride_size + 1; -} - -static bool CalculatePadding(ConvData& conv_data) { - size_t output_height{ 0 }; - size_t output_width{ 0 }; - - switch (conv_data.padding_type) { - case ngraph::op::PadType::EXPLICIT: - // all paddings already set - break; - case ngraph::op::PadType::VALID: - conv_data.pads_begin_height = 0; - conv_data.pads_begin_width = 0; - conv_data.pads_end_height = 0; - conv_data.pads_end_width = 0; - break; - case ngraph::op::PadType::SAME_LOWER: - case ngraph::op::PadType::SAME_UPPER: - { - output_height = conv_data.output_shape[2]; - output_width = conv_data.output_shape[3]; - - size_t pads_width = GetRequiredInputPadding(conv_data.input_width, conv_data.filter_width, - conv_data.filter_stride_width, conv_data.filter_dilation_width, output_width); - size_t pads_height = GetRequiredInputPadding(conv_data.input_height, conv_data.filter_height, - conv_data.filter_stride_height, conv_data.filter_dilation_height, output_height); - - conv_data.pads_begin_width = conv_data.pads_end_width = pads_width / 2; - conv_data.pads_begin_height = conv_data.pads_end_height = pads_height / 2; - - if (conv_data.padding_type == ngraph::op::PadType::SAME_LOWER) { - conv_data.pads_begin_width += (pads_width % 2); - conv_data.pads_begin_height += (pads_height % 2); - } else { - conv_data.pads_end_width += (pads_width % 2); - conv_data.pads_end_height += (pads_height % 2); - } - break; - } - default: - break; - } - - output_width = CalculateOutputSize(conv_data.input_width, conv_data.filter_width, conv_data.filter_stride_width, - conv_data.filter_dilation_width, conv_data.pads_begin_width + conv_data.pads_end_width); - output_height = CalculateOutputSize(conv_data.input_height, conv_data.filter_height, conv_data.filter_stride_height, - conv_data.filter_dilation_height, conv_data.pads_begin_height + conv_data.pads_end_height); - - IE_ASSERT(output_width == conv_data.output_shape[3]); - IE_ASSERT(output_height == conv_data.output_shape[2]); - - // Check if any calculated padding is non-zero, otherwise there is no need to decompose such convolution - return conv_data.pads_begin_height || conv_data.pads_end_height || conv_data.pads_begin_width || conv_data.pads_end_width; + pool_kernel.size() == 2 && pool_strides.size() == 2); } static std::shared_ptr FlatCrop(ngraph::Output input, size_t offset, size_t size) { @@ -227,7 +145,7 @@ static std::shared_ptr CreatePaddedNet(std::shared_ptrinput_value(0).get_shape()) }), false); - // zero padding + // Constant with zero padding auto const_holding_padding = std::make_shared(conv_data.element_type, ngraph::Shape{ 1, biggest_padding }, 0); copy_runtime_info(conv, const_holding_padding); @@ -342,9 +260,6 @@ static bool Convert(std::shared_ptr leading_transpose, if (max_pool && !VerifyMaxPool(std::dynamic_pointer_cast(max_pool))) return false; - if (!CalculatePadding(conv_data)) - return false; - GeneratePadding(std::dynamic_pointer_cast(leading_transpose), std::dynamic_pointer_cast(conv), conv_data); diff --git a/inference-engine/tests/functional/plugin/gna/pass_tests/padded2valid_conv.cpp b/inference-engine/tests/functional/plugin/gna/pass_tests/convert_padded2valid_conv.cpp similarity index 98% rename from inference-engine/tests/functional/plugin/gna/pass_tests/padded2valid_conv.cpp rename to inference-engine/tests/functional/plugin/gna/pass_tests/convert_padded2valid_conv.cpp index 010bbd7a5c0..0823567e578 100644 --- a/inference-engine/tests/functional/plugin/gna/pass_tests/padded2valid_conv.cpp +++ b/inference-engine/tests/functional/plugin/gna/pass_tests/convert_padded2valid_conv.cpp @@ -247,10 +247,10 @@ const std::vector> configs2D = { }; const std::vector padTypes = { + op::PadType::VALID, op::PadType::EXPLICIT, op::PadType::SAME_LOWER, - op::PadType::SAME_UPPER, - op::PadType::VALID + op::PadType::SAME_UPPER }; const std::vector models = { @@ -277,14 +277,14 @@ const std::vector> maxpool1DPools = { {1, 2} }; const std::vector> maxpool1DStrides = { {1, 1} }; const std::vector> input2DNHWC = { {1, 16, 16, 32} }; -const std::vector> kernels2D = { {2, 2}, {4, 1}, {1, 3}}; +const std::vector> kernels2D = { {2, 2}, {4, 1}, {1, 3} }; const std::vector> strides2D = { {1, 1}, {1, 2}, {2, 1}, {2, 2} }; const std::vector> padBegins2D = { {1, 2} }; const std::vector> padEnds2D = { {3, 1} }; const std::vector> dilations2D = { {1, 1} }; -const std::vector numOutChannels2D = { 32 }; -const std::vector> biases2D = { {1, 32, 1, 1} }; -const std::vector> transpBiases2D = { {1, 1, 1, 32} }; +const std::vector numOutChannels2D = { 8 }; +const std::vector> biases2D = { {1, 8, 1, 1} }; +const std::vector> transpBiases2D = { {1, 1, 1, 8} }; const std::vector> maxpool2DPools = { {2, 2} }; const std::vector> maxpool2DStrides = { {2, 1} }; diff --git a/inference-engine/tests/unit/gna/ngraph/transformations/gna_convert_padded2valid_conv.cpp b/inference-engine/tests/unit/gna/ngraph/transformations/gna_convert_padded2valid_conv.cpp new file mode 100644 index 00000000000..b8259bf3d84 --- /dev/null +++ b/inference-engine/tests/unit/gna/ngraph/transformations/gna_convert_padded2valid_conv.cpp @@ -0,0 +1,453 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include + +#include "transformations/convert_padded2valid_conv.hpp" +#include "common_test_utils/ngraph_test_utils.hpp" +#include +#include +#include +#include + +namespace testing { + +namespace { + +enum class modelType { + TranspConvTransp = 0, /* Transpose(NHWC->NCHW) => Conv => Transpose(NCHW->NHWC) */ + TranspConvBcastAddTransp, /* Transpose(NHWC->NCHW) => Conv => Broadcasted Add (Bias) => Transpose(NCHW->NHWC) */ + TranspConvBcastAddMaxPoolTransp, /* Transpose(NHWC->NCHW) => Conv => Broadcasted Add (Bias) => MaxPooling => Transpose(NCHW->NHWC) (2D Max Pool case) */ + TranspConvBcastAddActTransp, /* Transpose(NHWC->NCHW) => Conv => Broadcasted Add (Bias) => Activation Function => Transpose(NCHW->NHWC) */ + TranspConvBcastAddMaxPoolActTransp, /* Transpose(NHWC->NCHW) => Conv => Broadcasted Add (Bias) => MaxPool => Activation Function => Transpose(NCHW->NHWC) */ + TranspConvTranspBcastAdd, /* Transpose(NHWC->NCHW) => conv => Transpose(NCHW->NHWC) => Bias */ + TranspConvTranspBcastAddAct /* Transpose(NHWC->NCHW) => Conv => Transpose(NCHW->NHWC) => Bias => Activation Function */ +}; + +struct ConvData { + size_t input_height; + size_t input_width; + size_t input_channel_count; + size_t pads_begin_width; + size_t pads_begin_height; + size_t pads_end_width; + size_t pads_end_height; +}; + +void GetConvParams(std::shared_ptr conv, ConvData& conv_data) { + conv_data.input_channel_count = conv->input_value(0).get_shape()[1]; + conv_data.input_height = conv->input_value(0).get_shape()[2]; + conv_data.input_width = conv->input_value(0).get_shape()[3]; + conv_data.pads_begin_height = conv->get_pads_begin()[0]; + conv_data.pads_begin_width = conv->get_pads_begin()[1]; + conv_data.pads_end_height = conv->get_pads_end()[0]; + conv_data.pads_end_width = conv->get_pads_end()[1]; +} + +std::shared_ptr createFunction(const modelType& model, + const ngraph::Output& input_node, + const ngraph::Shape& filters_shape, + const ngraph::Strides& conv_stride, + const ngraph::CoordinateDiff& pads_begin, + const ngraph::CoordinateDiff& pads_end, + const ngraph::Strides& conv_dilation, + const ngraph::Shape& bias_shape, + const ngraph::Strides& maxpool_stride, + const ngraph::Shape& maxpool_shape, + const ngraph::op::PadType& pad_type, + ConvData* conv_data) { + auto transpose_in_order = std::make_shared(ngraph::element::i64, ngraph::Shape{4}, ngraph::Shape{0, 3, 1, 2}); + auto transpose_in = std::make_shared(input_node, transpose_in_order); + auto filters = std::make_shared(ngraph::element::i64, + ngraph::Shape{4, input_node.get_shape()[3], filters_shape[0], filters_shape[1]}); + auto conv = std::make_shared(transpose_in, filters, conv_stride, pads_begin, pads_end, conv_dilation, pad_type); + if (conv_data) + GetConvParams(conv, *conv_data); + auto transpose_out_order = std::make_shared(ngraph::element::i64, ngraph::Shape{4}, ngraph::Shape{0, 2, 3, 1}); + auto bias_const = std::make_shared(ngraph::element::i64, bias_shape); + ngraph::Output last_op = std::make_shared(conv, transpose_out_order); + + switch (model) { + case modelType::TranspConvBcastAddTransp: + { + auto bcast_add = std::make_shared(conv, bias_const); + last_op = std::make_shared(bcast_add, transpose_out_order); + } + break; + + case modelType::TranspConvBcastAddMaxPoolTransp: + { + auto bcast_add = std::make_shared(conv, bias_const); + auto maxpool = std::make_shared(bcast_add, maxpool_stride, ngraph::Shape{0, 0}, ngraph::Shape{0, 0}, maxpool_shape, + ngraph::op::RoundingType::FLOOR, ngraph::op::PadType::VALID); + auto transpose = std::make_shared(maxpool, transpose_out_order); + last_op = std::make_shared(transpose); + } + break; + + case modelType::TranspConvBcastAddActTransp: + { + auto bcast_add = std::make_shared(conv, bias_const); + auto activation = std::make_shared(bcast_add); + last_op = std::make_shared(activation, transpose_out_order); + } + break; + + case modelType::TranspConvBcastAddMaxPoolActTransp: + { + auto bcast_add = std::make_shared(conv, bias_const); + auto maxpool = std::make_shared(bcast_add, maxpool_stride, ngraph::Shape{0, 0}, ngraph::Shape{0, 0}, maxpool_shape, + ngraph::op::RoundingType::FLOOR, ngraph::op::PadType::VALID); + auto activation = std::make_shared(maxpool); + last_op = std::make_shared(activation, transpose_out_order); + } + break; + + case modelType::TranspConvTranspBcastAdd: + { + last_op = std::make_shared(last_op, bias_const); + } + break; + + case modelType::TranspConvTranspBcastAddAct: + { + auto bcast_add = std::make_shared(last_op, bias_const); + last_op = std::make_shared(bcast_add); + } + break; + + case modelType::TranspConvTransp: + default: + break; + } + + return std::make_shared(last_op); +} + +std::shared_ptr get_initial_function(const modelType& model, + const ngraph::PartialShape& input_shape, + const ngraph::Shape& filters_shape, + const ngraph::Strides& conv_stride, + const ngraph::CoordinateDiff& pads_begin, + const ngraph::CoordinateDiff& pads_end, + const ngraph::Strides& conv_dilation, + const ngraph::Shape& bias_shape, + const ngraph::Strides& maxpool_stride, + const ngraph::Shape& maxpool_shape, + const ngraph::op::PadType& pad_type, + ConvData& conv_data) { + auto inputParams = std::make_shared(ngraph::element::i64, input_shape); + auto result = createFunction(model, inputParams, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation, bias_shape, + maxpool_stride, maxpool_shape, pad_type, &conv_data); + return std::make_shared(ngraph::ResultVector{result}, ngraph::ParameterVector{inputParams}); +} + +// --------------------------------------------------------------------------------------------------------------------- + +class ConvertPadded2ValidConvTestInvalidFixture : public CommonTestUtils::TestsCommon, + public ::testing::WithParamInterface> { +public: + void SetUp() override; +public: + std::shared_ptr function, reference_function; + modelType model; +}; + +void ConvertPadded2ValidConvTestInvalidFixture::SetUp() { + ngraph::PartialShape input_shape; + ngraph::Shape filters_shape, bias_shape, maxpool_shape; + ngraph::Strides conv_stride, conv_dilation, maxpool_stride; + ngraph::CoordinateDiff pads_begin, pads_end; + ngraph::op::PadType pad_type; + ConvData conv_data; + std::tie(model, input_shape, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation, + bias_shape, maxpool_stride, maxpool_shape, pad_type) = this->GetParam(); + + function = get_initial_function(model, input_shape, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation, + bias_shape, maxpool_stride, maxpool_shape, pad_type, conv_data); + reference_function = get_initial_function(model, input_shape, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation, + bias_shape, maxpool_stride, maxpool_shape, pad_type, conv_data); +} + +// --------------------------------------------------------------------------------------------------------------------- + +class ConvertPadded2ValidConvTestFixture: public CommonTestUtils::TestsCommon, + public ::testing::WithParamInterface> { +public: + void SetUp() override; + std::shared_ptr get_reference(const modelType& model, + const ngraph::PartialShape& input_shape, + const ngraph::Shape& filters_shape, + const ngraph::Strides& conv_stride, + const ngraph::CoordinateDiff& pads_begin, + const ngraph::CoordinateDiff& pads_end, + const ngraph::Strides& conv_dilation, + const ngraph::Shape& bias_shape, + const ngraph::Strides& maxpool_stride, + const ngraph::Shape& maxpool_shape, + const ngraph::op::PadType& pad_type, + const ConvData& conv_data); +public: + std::shared_ptr function, reference_function; + modelType model; +}; + +void ConvertPadded2ValidConvTestFixture::SetUp() { + ngraph::PartialShape input_shape; + ngraph::Shape filters_shape, bias_shape, maxpool_shape; + ngraph::Strides conv_stride, conv_dilation, maxpool_stride; + ngraph::CoordinateDiff pads_begin, pads_end; + ngraph::op::PadType pad_type; + ConvData conv_data; + std::tie(model, input_shape, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation, + bias_shape, maxpool_stride, maxpool_shape, pad_type) = this->GetParam(); + + function = get_initial_function(model, input_shape, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation, + bias_shape, maxpool_stride, maxpool_shape, pad_type, conv_data); + reference_function = get_reference(model, input_shape, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation, + bias_shape, maxpool_stride, maxpool_shape, pad_type, conv_data); +} + +std::shared_ptr FlatCrop(ngraph::Output input, size_t offset, size_t size) { + return std::make_shared( + input, // data + ngraph::opset7::Constant::create(ngraph::element::i64, ngraph::Shape{2}, {(size_t)0, offset}), // begin sice index + ngraph::opset7::Constant::create(ngraph::element::i64, ngraph::Shape{2}, {(size_t)0, offset + size}), // end slice index + ngraph::opset7::Constant::create(ngraph::element::i64, ngraph::Shape{2}, {(size_t)1, (size_t)1}), // strides + std::vector{1, 0}, // begin mask + std::vector{1, 0}); // end mask +} + +void InsertPadding(ngraph::OutputVector& input_rows_to_concat, size_t size, + const std::shared_ptr padding_const, size_t biggest_padding) { + + if (size == biggest_padding) { + input_rows_to_concat.push_back(padding_const); + } else { + auto slice = FlatCrop(padding_const, 0, size); + input_rows_to_concat.push_back(slice); + } +} + +std::shared_ptr CreatePaddedNet(const ngraph::Output& input_node, + const ConvData& conv_data) { + size_t flat_left_padding = conv_data.input_channel_count * conv_data.pads_begin_width; + size_t flat_right_padding = conv_data.input_channel_count * conv_data.pads_end_width; + size_t padded_row_size = flat_left_padding + conv_data.input_channel_count * conv_data.input_width + flat_right_padding; + size_t flat_top_padding = padded_row_size * conv_data.pads_begin_height; + size_t flat_bottom_padding = padded_row_size * conv_data.pads_end_height; + size_t biggest_padding = std::max(std::max(flat_left_padding, flat_right_padding), std::max(flat_top_padding, flat_bottom_padding)); + + if (conv_data.input_height > 1 && (flat_top_padding > 1 || flat_bottom_padding > 1)) { + biggest_padding = biggest_padding > padded_row_size ? biggest_padding : padded_row_size; + } + + if (!biggest_padding) + return nullptr; + + auto flat_input = std::make_shared(input_node, + ngraph::opset7::Constant::create(ngraph::element::i64, ngraph::Shape{2}, + ngraph::Shape{1ull, shape_size(input_node.get_shape())}), false); + + // Constant with zero padding + auto const_holding_padding = std::make_shared(ngraph::element::i64, ngraph::Shape{1, biggest_padding}, 0); + + std::shared_ptr original_row = flat_input; + ngraph::OutputVector input_rows_to_concat; + + // Add top padding + for (size_t p = 0; p < conv_data.pads_begin_height; p++) { + InsertPadding(input_rows_to_concat, padded_row_size, const_holding_padding, biggest_padding); + } + + if (flat_left_padding || flat_right_padding) { + // Pad every row of input plain if neccessary + for (size_t h = 0; h < conv_data.input_height; h++) { + // left padding input right padding + // | | | + // +--------------+-----------+ + // | + // concat + + if (conv_data.input_height > 1) + original_row = FlatCrop(flat_input, h * conv_data.input_width * conv_data.input_channel_count, + conv_data.input_width * conv_data.input_channel_count); + + ngraph::OutputVector single_row_concat_inputs; + if (flat_left_padding) { + InsertPadding(single_row_concat_inputs, flat_left_padding, const_holding_padding, biggest_padding); + } + single_row_concat_inputs.push_back(original_row); + if (flat_right_padding) { + InsertPadding(single_row_concat_inputs, flat_right_padding, const_holding_padding, biggest_padding); + } + auto padded_row_concat = std::make_shared(single_row_concat_inputs, 1); + + input_rows_to_concat.push_back(padded_row_concat); + } + } else { + input_rows_to_concat.push_back(original_row); + } + + // Bottom padding + for (size_t p = 0; p < conv_data.pads_end_height; p++) { + InsertPadding(input_rows_to_concat, padded_row_size, const_holding_padding, biggest_padding); + } + + auto padded_input_plane = std::make_shared(input_rows_to_concat, 1); + return padded_input_plane; +} + +std::shared_ptr ConvertPadded2ValidConvTestFixture::get_reference(const modelType& model, + const ngraph::PartialShape& input_shape, + const ngraph::Shape& filters_shape, + const ngraph::Strides& conv_stride, + const ngraph::CoordinateDiff& pads_begin, + const ngraph::CoordinateDiff& pads_end, + const ngraph::Strides& conv_dilation, + const ngraph::Shape& bias_shape, + const ngraph::Strides& maxpool_stride, + const ngraph::Shape& maxpool_shape, + const ngraph::op::PadType& pad_type, + const ConvData& conv_data) { + auto inputParams = std::make_shared(ngraph::element::i64, input_shape); + + // Add padding where neccessary + + // padding + // padding + // ... row ... + // ... row ... + // ........... + // ... row ... + // padding + // padding + auto padded_input_plane = CreatePaddedNet(inputParams, conv_data); + std::shared_ptr result; + + if (padded_input_plane) { + auto shape_const = std::make_shared(ngraph::element::i64, ngraph::Shape{4}, + ngraph::Shape{static_cast(1), + conv_data.pads_begin_height + conv_data.input_height + conv_data.pads_end_height, + conv_data.pads_begin_width + conv_data.input_width + conv_data.pads_end_width, + conv_data.input_channel_count}); + auto padded_input_plane_reshaped = std::make_shared(padded_input_plane, shape_const, false); + result = createFunction(model, padded_input_plane_reshaped, filters_shape, conv_stride, + ngraph::CoordinateDiff{0, 0}, ngraph::CoordinateDiff{0, 0}, conv_dilation, bias_shape, + maxpool_stride, maxpool_shape, ngraph::op::PadType::EXPLICIT, nullptr); + } else { + // Valid padding + result = createFunction(model, inputParams, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation, bias_shape, + maxpool_stride, maxpool_shape, pad_type, nullptr); + } + + return std::make_shared(ngraph::ResultVector{result}, ngraph::ParameterVector{inputParams}); +} + +// --------------------------------------------------------------------------------------------------------------------- + +void execute_test(const modelType& model, std::shared_ptr function, std::shared_ptr reference_function) { + ngraph::pass::Manager manager; + manager.register_pass(); + + switch (model) { + default: + case modelType::TranspConvTransp: + manager.register_pass(); + break; + case modelType::TranspConvBcastAddTransp: + manager.register_pass(); + break; + case modelType::TranspConvBcastAddMaxPoolTransp: + manager.register_pass(); + break; + case modelType::TranspConvBcastAddActTransp: + manager.register_pass(); + break; + case modelType::TranspConvBcastAddMaxPoolActTransp: + manager.register_pass(); + break; + case modelType::TranspConvTranspBcastAdd: + manager.register_pass(); + break; + case modelType::TranspConvTranspBcastAddAct: + manager.register_pass(); + break; + } + + manager.run_passes(function); + const FunctionsComparator func_comparator = FunctionsComparator::with_default().enable(FunctionsComparator::ATTRIBUTES); + const FunctionsComparator::Result result = func_comparator(function, reference_function); + ASSERT_TRUE(result.valid); +} + +TEST_P(ConvertPadded2ValidConvTestFixture, CompareFunctions) { + execute_test(model, function, reference_function); +} + +INSTANTIATE_TEST_SUITE_P(ConvertPadded2ValidConvTestSuite, ConvertPadded2ValidConvTestFixture, + ::testing::Values( + std::make_tuple(modelType::TranspConvTransp, ngraph::PartialShape{1, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1}, + ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1}, + ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT), + std::make_tuple(modelType::TranspConvBcastAddTransp, ngraph::PartialShape{1, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1}, + ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1}, + ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT), + std::make_tuple(modelType::TranspConvBcastAddMaxPoolTransp, ngraph::PartialShape{1, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1}, + ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1}, + ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT), + std::make_tuple(modelType::TranspConvBcastAddActTransp, ngraph::PartialShape{1, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1}, + ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1}, + ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::SAME_LOWER), + std::make_tuple(modelType::TranspConvBcastAddMaxPoolActTransp, ngraph::PartialShape{1, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1}, + ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1}, + ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::SAME_UPPER), + std::make_tuple(modelType::TranspConvTranspBcastAdd, ngraph::PartialShape{1, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1}, + ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1}, + ngraph::Shape{1, 1, 1, 4}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT), + std::make_tuple(modelType::TranspConvTranspBcastAddAct, ngraph::PartialShape{1, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1}, + ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1}, + ngraph::Shape{1, 1, 1, 4}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT))); + +TEST_P(ConvertPadded2ValidConvTestInvalidFixture, CompareFunctions) { + execute_test(model, function, reference_function); +} + +INSTANTIATE_TEST_SUITE_P(ConvertPadded2ValidConvInvalidTestSuite, ConvertPadded2ValidConvTestInvalidFixture, + ::testing::Values( + std::make_tuple(modelType::TranspConvTransp, ngraph::PartialShape{2, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1}, + ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1}, + ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::SAME_UPPER), + std::make_tuple(modelType::TranspConvBcastAddTransp, ngraph::PartialShape{2, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1}, + ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1}, + ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT), + std::make_tuple(modelType::TranspConvBcastAddMaxPoolTransp, ngraph::PartialShape{2, 16, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1}, + ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1}, + ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{5, 1}, ngraph::op::PadType::EXPLICIT), + std::make_tuple(modelType::TranspConvBcastAddActTransp, ngraph::PartialShape{2, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1}, + ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1}, + ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::SAME_LOWER), + std::make_tuple(modelType::TranspConvBcastAddMaxPoolActTransp, ngraph::PartialShape{2, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1}, + ngraph::CoordinateDiff{0, 5}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1}, + ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 4}, ngraph::op::PadType::SAME_UPPER), + std::make_tuple(modelType::TranspConvTranspBcastAdd, ngraph::PartialShape{2, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1}, + ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1}, + ngraph::Shape{1, 1, 1, 4}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT), + std::make_tuple(modelType::TranspConvTranspBcastAddAct, ngraph::PartialShape{2, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1}, + ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1}, + ngraph::Shape{1, 1, 1, 4}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT))); + +} // namespace + +} // namespace testing From 5d6fa64621f673fec0351d522313c2443fea6471 Mon Sep 17 00:00:00 2001 From: Taylor Yeonbok Lee Date: Thu, 8 Jul 2021 18:25:16 +0900 Subject: [PATCH 07/13] [IE CLDNN] Improve bfyx convolution performance for shallow output ch (#6399) --- .../convolution_kernel_bfyx_os_iyx_osv16.cpp | 15 +++++++++++---- .../convolution_kernel_bfyx_os_iyx_osv16.h | 11 +++++++++++ .../convolution_gpu_bfyx_os_iyx_osv16.cl | 9 ++++----- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/convolution/convolution_kernel_bfyx_os_iyx_osv16.cpp b/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/convolution/convolution_kernel_bfyx_os_iyx_osv16.cpp index a80696c0b60..bef3794a657 100644 --- a/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/convolution/convolution_kernel_bfyx_os_iyx_osv16.cpp +++ b/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/convolution/convolution_kernel_bfyx_os_iyx_osv16.cpp @@ -9,7 +9,6 @@ namespace kernel_selector { // Sub-group size used by "kernel_name_bfyx_os_iyx_osv16" kernel. -constexpr size_t sub_group_size = 16; ConvolutionKernel_bfyx_os_iyx_osv16::ConvolutionKernel_bfyx_os_iyx_osv16() : ConvolutionKernelBase("convolution_gpu_bfyx_os_iyx_osv16") { @@ -94,6 +93,9 @@ static void shrink_blocks_to_output_size(size_t output_x, size_t output_y, size_ block_x -= unused_x / simds_x; block_y -= unused_y / simds_y; + + block_x = Align(block_x, 2); + block_y = Align(block_y, 2); } ConvolutionKernel_bfyx_os_iyx_osv16::AutoTuneOption ConvolutionKernel_bfyx_os_iyx_osv16::GetAutoTuneOptions( @@ -107,9 +109,11 @@ ConvolutionKernel_bfyx_os_iyx_osv16::AutoTuneOption ConvolutionKernel_bfyx_os_iy const convolution_params& cp = static_cast(p); + const auto& sub_group_size = GetSubGroupSize(cp); + if (cp.stride.x == 1 && cp.stride.y == 1) { if (cp.filterSize.x == 1 && cp.filterSize.y == 1) { - option.blockWidth = 16; + option.blockWidth = sub_group_size; option.blockHeight = 1; option.prefetch = 4; // if less than 16 values is required to compute one single row of output @@ -143,13 +147,13 @@ ConvolutionKernel_bfyx_os_iyx_osv16::AutoTuneOption ConvolutionKernel_bfyx_os_iy if (cp.filterSize.x != 1 || cp.filterSize.y != 1 || cp.output.Batch().v != 1) { shrink_blocks_to_output_size(cp.output.X().v, cp.output.Y().v, option.blockWidth, option.blockHeight); } - return option; } ConvolutionKernelBase::DispatchData ConvolutionKernel_bfyx_os_iyx_osv16::SetDefault(const convolution_params& cp, int autoTuneIndex) const { DispatchData dispatchData = ConvolutionKernelBase::SetDefault(cp); + const auto& sub_group_size = GetSubGroupSize(cp); const auto of_maps = cp.output.Feature().v; const auto of_maps_per_group = of_maps / cp.groups; @@ -196,6 +200,9 @@ bool ConvolutionKernel_bfyx_os_iyx_osv16::Validate(const Params& p, const option JitConstants ConvolutionKernel_bfyx_os_iyx_osv16::GetJitConstants(const convolution_params& params, const DispatchData& dispatchData) const { + const convolution_params& cp = static_cast(params); + const auto& sub_group_size = GetSubGroupSize(cp); + const auto of_maps = params.output.Feature().v; const auto of_maps_per_group = of_maps / params.groups; const size_t of_threads_per_batch = RoundUp(of_maps_per_group, sub_group_size); @@ -209,7 +216,7 @@ JitConstants ConvolutionKernel_bfyx_os_iyx_osv16::GetJitConstants(const convolut jit.Merge(MakeFusedOpsJitConstants(params, {conf_scalar})); } - + jit.AddConstant(MakeJitConstant("OSV_SIZE", 16)); jit.AddConstant(MakeJitConstant("SUB_GROUP_SIZE", dispatchData.lws[2])); jit.AddConstant(MakeJitConstant("OUTPUT_BLOCK_WIDTH", dispatchData.cldnnStyle.blockWidth)); jit.AddConstant(MakeJitConstant("OUTPUT_BLOCK_HEIGHT", dispatchData.cldnnStyle.blockHeight)); diff --git a/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/convolution/convolution_kernel_bfyx_os_iyx_osv16.h b/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/convolution/convolution_kernel_bfyx_os_iyx_osv16.h index 6bc617bb3f3..9da52609636 100644 --- a/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/convolution/convolution_kernel_bfyx_os_iyx_osv16.h +++ b/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/convolution/convolution_kernel_bfyx_os_iyx_osv16.h @@ -4,6 +4,7 @@ #pragma once +#include "api/cldnn/runtime/device_info.hpp" #include "convolution_kernel_base.h" #include #include @@ -34,6 +35,16 @@ protected: bool Validate(const Params& p, const optional_params& o) const override; bool NeedPaddedInput() const override { return true; } DispatchData SetDefault(const convolution_params& arg, int autoTuneIndex = -1) const override; + size_t GetSubGroupSize(const convolution_params& params) const { + if (params.engineInfo.computeUnitsCount <= 24) { + // Smaller # EU tends to be computation bounds. + // In such case, using larger worksize will result in larger computational inefficiency + // w.r.t the unalined output feature + return (params.output.Feature().v > 8) ? 16 : 8; + } else { + return 16; + } + } private: struct AutoTuneOption { diff --git a/inference-engine/thirdparty/clDNN/kernel_selector/core/cl_kernels/convolution_gpu_bfyx_os_iyx_osv16.cl b/inference-engine/thirdparty/clDNN/kernel_selector/core/cl_kernels/convolution_gpu_bfyx_os_iyx_osv16.cl index 679fa45de52..b622f1c1698 100644 --- a/inference-engine/thirdparty/clDNN/kernel_selector/core/cl_kernels/convolution_gpu_bfyx_os_iyx_osv16.cl +++ b/inference-engine/thirdparty/clDNN/kernel_selector/core/cl_kernels/convolution_gpu_bfyx_os_iyx_osv16.cl @@ -83,12 +83,11 @@ KERNEL(convolution_gpu_bfyx_os_iyx_osv16)( uint fmg = feature_idx / SUB_GROUP_SIZE; const uint g = split_idx; #endif - UNIT_TYPE in[IN_BLOCK_ARRAY_SIZE]; UNIT_TYPE out[OUTPUT_BLOCK_WIDTH * OUTPUT_BLOCK_HEIGHT]; UNIT_TYPE w[PREFETCH]; uint in_addr; - uint weight_addr = fmg * FILTER_IFM_NUM * FILTER_SIZE_X * FILTER_SIZE_Y * SUB_GROUP_SIZE + lid; + uint weight_addr = fmg * FILTER_IFM_NUM * FILTER_SIZE_X * FILTER_SIZE_Y * OSV_SIZE + lid; #if GROUPED weight_addr += g * FILTER_GROUPS_PITCH; @@ -156,7 +155,7 @@ KERNEL(convolution_gpu_bfyx_os_iyx_osv16)( in_addr += INPUT0_FEATURE_PITCH; for(int pf=0; pf Date: Thu, 8 Jul 2021 13:01:54 +0300 Subject: [PATCH 08/13] Extract OpenVINO version from header, if CI one is not defined (#6555) --- cmake/developer_package/version.cmake | 25 +++++++++++-------- .../mock_mo_python_api/CMakeLists.txt | 2 +- ngraph/frontend/CMakeLists.txt | 5 ---- ngraph/frontend/paddlepaddle/CMakeLists.txt | 2 -- ngraph/python/CMakeLists.txt | 2 +- 5 files changed, 16 insertions(+), 20 deletions(-) diff --git a/cmake/developer_package/version.cmake b/cmake/developer_package/version.cmake index e807a3ea31f..054bc10c78e 100644 --- a/cmake/developer_package/version.cmake +++ b/cmake/developer_package/version.cmake @@ -31,19 +31,18 @@ macro(ie_parse_ci_build_number) set(IE_VERSION_MAJOR ${CMAKE_MATCH_1}) set(IE_VERSION_MINOR ${CMAKE_MATCH_2}) set(IE_VERSION_PATCH ${CMAKE_MATCH_3}) - set(has_ci_version ON) - else() - set(IE_VERSION_MAJOR 0) - set(IE_VERSION_MINOR 0) - set(IE_VERSION_PATCH 0) endif() if(NOT DEFINED repo_root) message(FATAL_ERROR "repo_root is not defined") endif() - if(DEFINED IEDevScripts_DIR AND DEFINED OpeenVINO_SOURCE_DIR AND NOT DEFINED custom_build) - set(ie_version_hpp "${IE_MAIN_SOURCE_DIR}/include/ie_version.hpp") + macro(ie_get_hpp_version) + if(NOT DEFINED OpenVINO_SOURCE_DIR) + return() + endif() + + set(ie_version_hpp "${OpenVINO_SOURCE_DIR}/inference-engine/include/ie_version.hpp") if(NOT EXISTS ${ie_version_hpp}) message(FATAL_ERROR "File ie_version.hpp with IE_VERSION definitions is not found") endif() @@ -57,6 +56,13 @@ macro(ie_parse_ci_build_number) string(REGEX REPLACE ".+IE_VERSION_PATCH[ ]+([0-9]+).*" "\\1" IE_VERSION_PATCH_HPP "${IE_VERSION_PARTS}") + set(ie_hpp_version_is_found ON) + endmacro() + + # detect OpenVINO version via ie_version.hpp + ie_get_hpp_version() + + if(ie_hpp_version_is_found) foreach(var IE_VERSION_MAJOR IE_VERSION_MINOR IE_VERSION_PATCH) if(DEFINED ${var} AND NOT ${var} EQUAL ${var}_HPP) message(FATAL_ERROR "${var} parsed from CI_BUILD_NUMBER (${${var}}) \ @@ -66,13 +72,10 @@ macro(ie_parse_ci_build_number) set(${var} ${${var}_HPP}) endif() endforeach() - elseif(has_ci_version) - message(WARNING "OpeenVINO_SOURCE_DIR is not defined. No way to compare versions") - else() - message(WARNING "No way to detect OpenVINO version. Supposing 0.0.0.0") endif() set(IE_VERSION "${IE_VERSION_MAJOR}.${IE_VERSION_MINOR}.${IE_VERSION_PATCH}") + message(STATUS "OpenVINO version is ${IE_VERSION}") endmacro() if (DEFINED ENV{CI_BUILD_NUMBER}) diff --git a/model-optimizer/unit_tests/mock_mo_frontend/mock_mo_python_api/CMakeLists.txt b/model-optimizer/unit_tests/mock_mo_frontend/mock_mo_python_api/CMakeLists.txt index 711f85ecc2f..1a94414055b 100644 --- a/model-optimizer/unit_tests/mock_mo_frontend/mock_mo_python_api/CMakeLists.txt +++ b/model-optimizer/unit_tests/mock_mo_frontend/mock_mo_python_api/CMakeLists.txt @@ -8,7 +8,7 @@ set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_OLD ${CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY} set(CMAKE_PDB_OUTPUT_DIRECTORY_OLD ${CMAKE_PDB_OUTPUT_DIRECTORY}) set(PYTHON_VERSION python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}) -message("Python version=${PYTHON_VERSION}") +message(STATUS "Python version=${PYTHON_VERSION}") if(WIN32) set(PYTHON_BRIDGE_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/$/python_api/${PYTHON_VERSION}/) diff --git a/ngraph/frontend/CMakeLists.txt b/ngraph/frontend/CMakeLists.txt index 8a25cc9b650..b4afff783db 100644 --- a/ngraph/frontend/CMakeLists.txt +++ b/ngraph/frontend/CMakeLists.txt @@ -3,9 +3,6 @@ # if(NOT WIN32) - message(${CMAKE_SOURCE_DIR}/thirdparty/cmake_static_protobuf) - message(BINARY ${CMAKE_CURRENT_BINARY_DIR}) - # There seems no suitable other way to identify exact output binary name for libprotobuf if(CMAKE_BUILD_TYPE STREQUAL "Debug") # Use 'protobufd' directly as it is done in the same way in protobuf cmake files @@ -15,8 +12,6 @@ if(NOT WIN32) set(PROTOBUF_STATIC_LIB_OUTPUT ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${CMAKE_STATIC_LIBRARY_PREFIX}protobuf${CMAKE_STATIC_LIBRARY_SUFFIX}) endif() - message("Static protobuf lib: ${PROTOBUF_STATIC_LIB_OUTPUT}") - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/libprotobuf_static) add_custom_command( OUTPUT diff --git a/ngraph/frontend/paddlepaddle/CMakeLists.txt b/ngraph/frontend/paddlepaddle/CMakeLists.txt index bf5c396ac6c..cc6f300f8da 100644 --- a/ngraph/frontend/paddlepaddle/CMakeLists.txt +++ b/ngraph/frontend/paddlepaddle/CMakeLists.txt @@ -29,8 +29,6 @@ else() set(PDPD_PROTOC_EXECUTABLE $) endif() -message("PDPD_PROTOC_EXECUTABLE is [${PDPD_PROTOC_EXECUTABLE}]") - foreach(INFILE ${proto_files}) get_filename_component(FILE_DIR ${INFILE} DIRECTORY) get_filename_component(FILE_WE ${INFILE} NAME_WE) diff --git a/ngraph/python/CMakeLists.txt b/ngraph/python/CMakeLists.txt index 82b414d0499..2eb4b03a2e5 100644 --- a/ngraph/python/CMakeLists.txt +++ b/ngraph/python/CMakeLists.txt @@ -19,7 +19,7 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pybind11 EXCLUDE_FROM_ALL) # PYTHON_VERSION_MAJOR and PYTHON_VERSION_MINOR are defined inside pybind11 set(PYTHON_VERSION python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}) -message("Python version=${PYTHON_VERSION}") +message(STATUS "Python version=${PYTHON_VERSION}") set(LIBRARY_OUTPUT_DIRECTORY_BIN ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) if(OpenVINO_SOURCE_DIR) From ba3a667730da53176775c330c088481abd52fddb Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Thu, 8 Jul 2021 13:03:02 +0300 Subject: [PATCH 09/13] Used generator expression for CONFIG (#6557) --- cmake/developer_package/packaging.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/developer_package/packaging.cmake b/cmake/developer_package/packaging.cmake index fd7d39a35ec..4cb21210d4a 100644 --- a/cmake/developer_package/packaging.cmake +++ b/cmake/developer_package/packaging.cmake @@ -13,9 +13,9 @@ include(CPackComponent) set(IE_CPACK_IE_DIR deployment_tools/inference_engine) function(ie_cpack_set_library_dir) if(WIN32) - set(IE_CPACK_LIBRARY_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER}/${CMAKE_BUILD_TYPE} PARENT_SCOPE) - set(IE_CPACK_RUNTIME_PATH ${IE_CPACK_IE_DIR}/bin/${ARCH_FOLDER}/${CMAKE_BUILD_TYPE} PARENT_SCOPE) - set(IE_CPACK_ARCHIVE_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER}/${CMAKE_BUILD_TYPE} PARENT_SCOPE) + set(IE_CPACK_LIBRARY_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER}/$ PARENT_SCOPE) + set(IE_CPACK_RUNTIME_PATH ${IE_CPACK_IE_DIR}/bin/${ARCH_FOLDER}/$ PARENT_SCOPE) + set(IE_CPACK_ARCHIVE_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER}/$ PARENT_SCOPE) else() set(IE_CPACK_LIBRARY_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER} PARENT_SCOPE) set(IE_CPACK_RUNTIME_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER} PARENT_SCOPE) From b56164e80482d5755eef1bd9d43b46d94ae03cc2 Mon Sep 17 00:00:00 2001 From: Yegor Kruglov Date: Thu, 8 Jul 2021 13:55:29 +0300 Subject: [PATCH 10/13] [MO] Updating condition in TF Const value extracting (#6322) * update value extracting condition * added a comment * updated unittest * added a scalar test, little fix for scalar values extracting --- .../mo/front/tf/extractors/utils.py | 14 ++++++++-- .../mo/front/tf/extractors/utils_test.py | 27 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/model-optimizer/mo/front/tf/extractors/utils.py b/model-optimizer/mo/front/tf/extractors/utils.py index c8fac1de697..c9d07083b38 100644 --- a/model-optimizer/mo/front/tf/extractors/utils.py +++ b/model-optimizer/mo/front/tf/extractors/utils.py @@ -70,8 +70,18 @@ def tf_tensor_content(tf_dtype, shape, pb_tensor): log.error(decode_err_msg, extra={'is_warning': True}) value = np.array(type_helper[1](pb_tensor)) - if len(shape) == 0 or shape.prod() == 0: - if len(value) == 1: + # Ignore an empty value, if len(shape) > 1 + # For example, value = [] and shape = [1, 1, 0] + # This is needed to reshape this value later and to return reshaped value = [[[]]] + # Otherwise there can be failures during partial inference, because we are storing an empty value with incorrect + # shape + if len(shape) == 0 or (len(shape) == 1 and shape.prod() == 0): + try: + value_length = len(value) + except TypeError: + # case, when value is a scalar + value_length = 0 + if value_length == 1: # return scalar if shape is [] otherwise broadcast according to shape try: return np.array(value[0], dtype=type_helper[0]) diff --git a/model-optimizer/unit_tests/mo/front/tf/extractors/utils_test.py b/model-optimizer/unit_tests/mo/front/tf/extractors/utils_test.py index b2ba651fba2..d9d3fc329c8 100644 --- a/model-optimizer/unit_tests/mo/front/tf/extractors/utils_test.py +++ b/model-optimizer/unit_tests/mo/front/tf/extractors/utils_test.py @@ -211,3 +211,30 @@ class TensorContentParsing(unittest.TestCase): with self.assertLogs(log.getLogger(), level="ERROR") as cm: result = tf_tensor_content(pb_tensor.dtype, shape, pb_tensor) self.assertEqual([warning_message, warning_message], cm.output) + + def test_empty_value(self): + pb_tensor = PB({ + 'dtype': 1, + 'float_val': [] + }) + + shape = int64_array([1, 1, 0]) + tf_dtype = pb_tensor.dtype + ref = np.array([[[]]], dtype=np.float32) + res = tf_tensor_content(tf_dtype, shape, pb_tensor) + + self.assertEqual(res.shape, ref.shape) + self.assertTrue(np.all(res == ref)) + + def test_scalar_value(self): + pb_tensor = PB({ + 'dtype': 3, + 'int_val': 4 + }) + + shape = int64_array([]) + tf_dtype = pb_tensor.dtype + ref = np.array(4, dtype=np.int32) + res = tf_tensor_content(tf_dtype, shape, pb_tensor) + + self.assertEqual(ref, res) From 975496df16a68f03dce558949452c747c6ad58ea Mon Sep 17 00:00:00 2001 From: azhogov Date: Thu, 8 Jul 2021 14:06:38 +0300 Subject: [PATCH 11/13] Convert *.png and *.bmp files to LFS --- .gitattributes | 7 +------ docs/IE_DG/img/applying_low_latency.png | 0 docs/IE_DG/img/applying_low_latency_2.png | 0 docs/IE_DG/img/llt2_use_const_initializer.png | 0 docs/IE_DG/img/low_latency_limitation_1.png | 0 docs/IE_DG/img/low_latency_limitation_2.png | 0 docs/img/OV-diagram-step1.png | Bin 22633 -> 130 bytes docs/img/OV-diagram-step4.png | Bin 18764 -> 130 bytes scripts/demo/car_1.bmp | Bin 1432032 -> 132 bytes 9 files changed, 1 insertion(+), 6 deletions(-) mode change 100755 => 100644 docs/IE_DG/img/applying_low_latency.png mode change 100755 => 100644 docs/IE_DG/img/applying_low_latency_2.png mode change 100755 => 100644 docs/IE_DG/img/llt2_use_const_initializer.png mode change 100755 => 100644 docs/IE_DG/img/low_latency_limitation_1.png mode change 100755 => 100644 docs/IE_DG/img/low_latency_limitation_2.png diff --git a/.gitattributes b/.gitattributes index de9c0b51d76..78133600185 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,7 +2,6 @@ # Set default behavior to automatically normalize line endings. ############################################################################### * text=auto - ############################################################################### # Set default behavior for command prompt diff. # @@ -11,9 +10,7 @@ # Note: This is only used by command line ############################################################################### #*.cs diff=csharp - *.py text eol=lf - ############################################################################### # Set the merge driver for project and solution files # @@ -36,7 +33,6 @@ #*.modelproj merge=binary #*.sqlproj merge=binary #*.wwaproj merge=binary - ############################################################################### # behavior for image files # @@ -45,7 +41,6 @@ #*.jpg binary #*.png binary #*.gif binary - ############################################################################### # diff behavior for common document formats # @@ -63,9 +58,9 @@ #*.PDF diff=astextplain #*.rtf diff=astextplain #*.RTF diff=astextplain - *.PNG filter=lfs diff=lfs merge=lfs -text *.png filter=lfs diff=lfs merge=lfs -text *.jpg filter=lfs diff=lfs merge=lfs -text *.gif filter=lfs diff=lfs merge=lfs -text *.vsdx filter=lfs diff=lfs merge=lfs -text +*.bmp filter=lfs diff=lfs merge=lfs -text diff --git a/docs/IE_DG/img/applying_low_latency.png b/docs/IE_DG/img/applying_low_latency.png old mode 100755 new mode 100644 diff --git a/docs/IE_DG/img/applying_low_latency_2.png b/docs/IE_DG/img/applying_low_latency_2.png old mode 100755 new mode 100644 diff --git a/docs/IE_DG/img/llt2_use_const_initializer.png b/docs/IE_DG/img/llt2_use_const_initializer.png old mode 100755 new mode 100644 diff --git a/docs/IE_DG/img/low_latency_limitation_1.png b/docs/IE_DG/img/low_latency_limitation_1.png old mode 100755 new mode 100644 diff --git a/docs/IE_DG/img/low_latency_limitation_2.png b/docs/IE_DG/img/low_latency_limitation_2.png old mode 100755 new mode 100644 diff --git a/docs/img/OV-diagram-step1.png b/docs/img/OV-diagram-step1.png index d1ff39f1aaa1eae2d292ce95ce5b17f6aa100181..da3212d0713bdbe5d3b3ffd4b2050867efd1bcdd 100644 GIT binary patch literal 130 zcmWN?%MrpL5CG6SRnUOpy8+S-EQ>Isl5sHytJimV7rlARm+Whud?-K28{qLW$ z;e0AS3Dsr9994497WN}yL`){P>WePPP&D964jyU)OyH8I5JSUgO>A02sJUp9DVJ6) Nq2Tc)Y3=Tu_yGqhC|3Xg literal 22633 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 CH%n#! diff --git a/docs/img/OV-diagram-step4.png b/docs/img/OV-diagram-step4.png index 75fe645a313e328ce548a5e4c6b375182663d502..7df9835e8e86e9eade5031f7683d1947fdcba7a4 100644 GIT binary patch literal 130 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 Hl+XkK3n9z& diff --git a/scripts/demo/car_1.bmp b/scripts/demo/car_1.bmp index 111cee4ff867d956ab12f685e64b3820ae7c70c9..ffdb8bf2ec306004e2bc097020aaf47bf3a5ff2d 100644 GIT binary patch literal 132 zcmWN?%MrpL5CG6SRnUOpyKG1|uq?uiN=7gTtJimV7r$p8FWJ^Q=b_ZSuiK-}?SK2^ zjmA^WlSy4hj9%ny$wD|Bx6+bD}C?Ws= literal 1432032 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
ytPB)5Ch*4qoT+>Olpsby0EIva z;0Z>nl9T=q923Puphj{biU>roS1I_&{p7N_l%ig%R*<8QEG%sU0#yW#VcHoinTt+A z!HrXpEVd_jJ|l%PPS7x>EL2SCpG|86iCkBhSt_6XxfwE+tSHu1zS8mt#KL2xmCPbG zP|B5wjipS&$pBrccH`uV1L^Q%1Wy9EHcuRXm@kkvV!W|)7 z3j#@$^ca0Y(jxRsl+`jgS(=sFZ_*eO`x@IB`XHNU5+@LD;cjinWO7OqHQ4B^UVSQlI(3js5zqWk~&A4?lXjnu`AO%t&oypgNV+>099fIbW` zwl`=SM32#R2q-Zlmm9Yf8U#275SAuEA-O)hX{Ia7VrJX$iE}&cBDm{rw;qAPYPQ4}@<%V@WT;dtvoIK2tZYX73$g~)7o`v z%G6!e6W5FyId|NMIlLaGX5@3#!=I}iv7l!7g7MET829Yl>Zw=;22&T!y8<99~~FJbJW?@299~=*?(BEYKh-S@(CDDSwJ5A<#6iEv6H8d z@<#=KNXQk^$G-fTQ9R0q<*}3L3x-_9%b(KEjPRin9|U9UUm&>RJQY||yddiEsnaL< ziTkIxXS+3U3>^W1X3#+NvI1sl5LW-}$OIt5@GwX$b=EdA1a43dw-g>?@YIk6VN6+Z z45jq12c2k>oL0_b(2y0l1R+RQ?lQ;#ny7-L^NHEU%wt~0w4>#aNo<^~8dyY!ngz$+ z=^Im=ISoZpKh}k1Q20l{UIUdRSxap3tT#Ah2!Tr~L+`SLLuOSBAN`M>T$iq9E>|pa zy{kPBA>lJB)jnJqne^|L!9HT7(IzY@C}C{NXai(-aqr01LM~fLNw3m^aE!5mkSRq{ zfhxR{|06uk#L6pM4D!4TS+F(T%#1aZk zE?Ad5^pT`gRN(|>nlS^NNMWyF6_h0zZHQzv+bsGGLKzLi5?M1j1`Icx+ksRfq>@G1 zkV%F?w3%k;lR+U?F-E1)p$O#IkrjieK-DM*>-Y2em?MYyktHrZSK{wBHpC+*(uYc% z$ADwpBG0~j?)0nYKe_eU<$HI4GWU58-gn;sWxz3Ce*4Xpn>Q}J{@T$~CyA?^2+>Zu zmw3g+4&XjRKhxXX1$RedjNHWL9Dj%*2;1mIA?5~T31c7#gdUB#*dxoyQc#1#93PMs zP$te}JdB}Wzy%RNw1ftWV-RqtPoV>Pvn*m=VS@){3g#d~2tq+hVSpK=(kjsFmR#Bl zA>hGH1C9Zfnxz(GA8eV0H*+y2*MiQ0kYh?9q={JhJe2v#bczY=^kegJ$*`X=%5b-0 zIOD6#YRZ!;&2^{3gR4&-F@nIvRFMcqMG#AW+YtEP;roi({>T~p`b zmhQ8Fm~^!tubaAK+=LZl#>^Wxs(<{5Uap!^eKjNd$5-`NSIw>+Ij3gC>jyCIgjCF2q?p03^=B}qmAc$fA!3NUAKO9@f>dYZ4i!C zIBQ|Wi9&!fr_UY-&2TBe&z?WYg`gQWT-x)!!ZT-2o<0NmK8g|pEH%LX%()Zi&Yyny zl@~9(d_KJgkKPoifNAK*z%eAzlWV`*_1ZfmaK-@g2t*))QV61rLq(~aV*E6wI27J2 zI2gxh49A!$BD@F?VWV(lfkaJRLrSv3Z_adMq*DU2csU}=`zm6bTOq=i! zHWnAP4CchGm~xSul*KD#IE_yKXFs&WVT|W7{LRPrl@1<1wCC7?&%U^G<%_%59^B^# zBY`q^zWo}3Z(m=#ee0Erzvfr3#WD04%a*@Uh;nQNL?*TrS23-nc48_4m?%r+7KjKq z4Am%$s6D{Ql0+?NNs3(%G=@W=4^VbWr5_4IR%(rECY&0P_=!27aEFerUJ(wr(9K;l%^3ksl7!V1C z64BP<1CCMvF+h_7#tb~bJHL1Xo;U{dz$ZJPnYsK{(hCX4Xb*=tjo}31`9+JCtXMgJ z;qs~x4OOFhz%h;O`=@psZ|FEZwevJ*GZUw79bdO%%-Ffr{OrJ}-f<&(xIi;wtJ1~W zd#i^}s~K5b!@B@6)gxMJ#@5$XPpacF-zg2?n5M?&_V#v~!IzZ)Fxa&Ux~UOxNEYcC>T07enhAb?bWFCdk(=T5;fd->J# zTo}K2;moh!c;)qrFJFA~)wkZc_?x$X{gj>iSK=6<4E+u`kSwl@9)pk(0?=S)Sq9Hx z%L`%#VIN9_JgHB3!aEfZ!*pS;NFo*Y7dXYKMUH24g9}i^AIi8gi4ZfDsadiKGxUK= zP(mc5AOhhepX()A%djUGdzO$f#sy~JNlR`&FDE7V?1YodRQ3?+_Db+i;CD9}Wn?c#=C4A;YmOfQl3!Efe zD)}UtPm)}Yc|vv3?e;mY2K!NiF@!;MT69sa&pjZMmEQ=mny43n{`3~`5?`7=u%B-&@kb&1sXw&DsSGDH#b0=* z_^HV42ln24c%Q=I)iJqDTCCHLy!BJumW+eoZ4|j}p*mzsm zkmW>zBcq2qU7an+PUBc9u1%AUDVzGU+uSyJ<9T1^`xgmUss6^x<9ufNp zNf8IdF_ABp5;!B>wO+xU;e+9tQGsc+pmsde9!*24`QN9tSlOl;U#Q^zY|o~s#OfifefjUP3A z+{j)og!BuMqr1nC?yMQzUOlR- zhm%~0>FcD7EQ>@bCa#tmU|gEw8su{wS$vZ#T_LQTd^x$O2DbPE{N~W^5{@AYa-&bn z^6@wZS6C7o6p)Q%l#1;jf&&^CxjZ5Y0-6+Rvhx@;LF^7XaVxPp?_x-98_cqKxT2J@ z0=c=FG6qoiL>UEDMpMz#+StP49^DX4a=+e@HFg`7zRXWW zo_Oipb*kRZW z>@Mmhni7MF$HsWk1N`4i;1bFL9Y8Aa@)%JI7)4Fs8$nEP%)~KpA&AWY$3)a0EQlU* zcoCQe)M9(&_<^`tg)lQ2O3_K+o2ZeB7&r(aI&H8SSy4nG5J`-6v{?gulEqYEE-{PX z42?=>P8c`?V-@EUUK!4UjYTJ>G3j8V`79w1R^YmgkzN) z$8a!H!ZD4Fjo=v0V}Lq98F37;o8lbCEM3Ldu2-#Dw|@D`jbp2uhmCBT(z2qVZA)Ft z_Q@@K8ann)ZroZsdCi2nrDMj-t{(RsM>6BaOy{Z|?KPu%Oz(v8()*U} z@vXPt;6tA`-+CRG!u8I3Z-PSJ|L|?Dk3MZp^YBYP$bBL!O;hf2|R(|&Z6K1(gWL#0tOZ|S4%h)FeT)CMn*0| z;214qLNj&Ag~x0*i9tTmLoVq}vTO#gE4O&QMlX&5${0o95n~Jhfnzw5p_CL3D~c3o zk=47-UE#r5`LPQqi**%9O zY@#uE;2yaPc=$oc{e-c1M-s}7L$*{tG-$~6*5C@(XiviJWbY+x2JU>Q|Fnrp^@(8! zIxKPSky#qmA;hFr?|`OQ#YalTbH0AGRD9WiPm~U(m;4^y2e^6d^;chf>HNuaXI}jE z>mOeK>?U8g{^|iACw=+bA2^Qz%J8`oU%-C#jf;nl9|OmvV92cI&1qY=c^;GF7-~15 ziem`m;08nfzYWLa;3G#Tx)q}URw9|#qJ2Oa4^C(jK!N5F@8N=#!JMoiiQ+WLR>5(F z21|V+2uIXJuKr0vVM7DxE4nivNR-t^L^33&hyzV=Nhe{ffomb3JTXxt%gGkA-Bre- zKm%v~qj58LbJhSkr`XRG$P&cB2@r-G|7=EP!Vtv_ixmv>=zk+GTp%Kj0m^vR5{ELN z7SCfqFilNOynqf35C_CV5s2c6R;^gFd?~?{A1+$CW@GKdmeJ!nrZg{}(zCNBlV)Qp`|JAPJOO~2P99;T_8J-N28ZhUuLO=n$g`^1{I+VL&b z;~HwJ>nGOLgJU>};m5A|Ap(Am0QdrkX=!d~ZJFB9(e&)IzkK73S1w)p;FC|@OMv6k z_dodP9XR-d3+&=``Rd2F@80<0%i9mWx_9NXPe3zVSFe2vQo#UD5kL=zE}vd`|HDrb zaM8@-AefuCuiX9eI@h;9-v9kSeV2Y;$^NxB=?9LdAOyf2N^j--M+P4Ryih=? zC0t9*;2NL|(h`06!3-iP)Nt%0R}XnEQv_fE31To{_T+fQIV6-(mg8AV%8Ez?E69*@ zQBAH#E@~TihaO2Roz|M=N&KL6e!C>{RY9qk`U-GYkxMK1KnU5tH$RVI5u(>7wtjJp zA1y_k2tNph4YSnaCxU@Xoo#}po<|hyF}7_{mj));FDN4A1*4R8!EJzg_XRkfb3b^) ziGJc9^^o@uS(MTMy`D{)rIWvgBlHP{F(VI17jaET%DIaUHtTgHh zp9tLAkfaS+Rvk|AvK9|b7}HLDB4}flPRw;&kRd%F*v=tuP$eFMo?xb*uv9?F&?74_ zot%&{uh6T6BSSHDnY7MZry>!K50$_%=^@`E=~RZVWv1_N9@)=z@aO@QXV0DCJm&bB zQ?I}C_QyA`^BpA)V?Z#1n8d&Rh9j9b-g*1T$rBtqa2~^lBCL%ao42sVuo1AUu$eHR z^bai|f8SiGsNqvN)imq!#pXQbKMR2xV-5W)bNT^hQ%{Z3tLK z!}Nv*!XBa`1?)i{>Mfgdv5Pj;MUqmvakK;*vM>k@g53yL8A2o(T*f-r=dvC!h{?k| zVNx+MAmw6G4>0FHv)v8Z(PTNetFxcS#va=>S+UQ@)@^Zk1O)`9hp`F4h{l{Dz!^`8 zgGN#VVmd^rJl@O63b+JPfP+*Z(9FEbSFd|}d-*_T#*7&p(g1e?!RUPTx;6aVG}ZBp z!Rpls$BY@*THm~IQuC4tjVmWKuBvNVJ83HKm02;he(B^13ntdgnKI$IhRJiLPM+N~ zWo~o*yw>`8E%nc}OzCT$(%Uqpr@4MwF%A@ z+0)(L)5EVIHIE$m%;LrKuU-4};lsN(Z(jNQ_OiTX(L5VD8<&b^pPg zFCX6h`r9v&0W@4_?tbz4oqIPCumsldu@T2DcfPoO_x=qu-+cGrr{917@ar$W`u5(} z-{1SE|MuIz{Oce8+yD5(|M*}3{OI?t=>_lT(Mzhpu*m==q-yGQ6U9^%F0JDPGAFJKoJ{;ko;zUG;3gVVdFq33JtKhov7VP zNwQzCcX;C@b3fJ|6;UMoSX@qHBn|Q`WF6|n2Imb^rg#WZMbw*@#Zvr%SzZb`>P3d4 z-oXO76z8rX=72jU#Y+`o7CxUWM4PRb8m%Hqg@Kwpscc=Lx6N=gG!GuGu!P8h@&>C3 zWh6rr#tONC@?ZlrgdF3LlPczwdXt!uTg=>n*=wL8_c1tzjDviS>F5c*#d+k++0z#; zT;RCnolicw`QQN`BykwSF$`#i=X?|Y>LG9S<@uO>e7o}~57+QfRXPpW$uIf-9LLa6 zw1iB^h)&oJND;^YL2wXRkt}Hf0HH?)K;uth4#UgT=O8?6dsF5O==?B?1U~JV0-d%7?K_s;d9zHdopx&aOMNDFo zZ)Gw4n9___OlD-rCCPS#tN};`Vgq-pM|LNN7deTkiJct5T=f_j#SAyfZ~~dJ&rleg zSV_S307lM941#C|IdBYLS%N??t(BL@0CXse2R!4S8h7m6&c%&^dJ=3$3)0DoJ`q^z$pKGt5+cLSo zZOY8%$=ywpx|%0_@Th61H{CYLP|lAI}i*iI3}T)f(R8Dx-!Gq z_+b(&_I-nakt1LHSYm(&8)gzsNx*|;;l`4p^7LH*?K_}YF5J0iS&|%{czGU^p7<@UeFyh*RKwdQ__6DkUViz#k3YJ4 z`}W;$zxA6+e5eGJ;o>|74N&Gc@4t8W#Bo1YN&&LKF>Dj8cXt)$Fdaqh22mm_MA!xd zhz8_BlN@k_3@8cXkkR0Tqy>ctxXS&AA*?R1OPR8{fp7s10U*c{Mg*7uE<{$e$7X1g z7qL<_5VD{l9}9;M4c($KP7oj}NDOg}~Z$XJ!v~|99D9fKY7h1KT_MHcIvG;bDozK=`TrXWSu* z8T$-{5fCHh0!lbs2?Uelm<0r;l&STnIyW88kyV|DrbWEGpKC`!T)~wzs z_0?6we+hi~>33gq9>X~b^7YTt6ENTyE)G-xF+9rxb`h@tWxy-{@~?m90=ocHIBo&l zfN20RJUzpQN|!(TkRkw=zx>NTQ;H%Fzq$Lx!<*m#^x%izJ^0g~fB3)u`%gdq{$YB5 zOit0K2 z@xvwO(kc#Pw(r`#J^e}+UtQuV79_`poWAVecL40-;*52RfaYgTiUo{PA`1aC!h`!x ziWtRX7U;=kom)FHW^M!)F^NW3Bq3xpkg`?B?cmB9xkr1(HLu<*3tGFJ;@F1`W)Mk~ z^qZZTHj;wuXGDu&7PV6}=R5|UAuO_gI~1LBrxvo{FWgGqhn zW+8_VmFir*Qv%ssydk3uy=GCwET^KfS;#RzDS}M6g6mlulJqtajx6IJAcl*_Vz~Am z+;jBg5sqZIUjNOTS8iPAca(S(=HZV&eD&KO!7g9@{-^ZY*T4M%PV$q_uAVy2H$l@^ zuW^WHLRmWaEp{sQ4(2f3!f-ppR!Z#zc#wpULRb)(fGlK4s6nzsgnTp@ZWMPa3K}cahVX7F~m^p^U2#5ws<1c3ifnz`?$lw?RzzRn)ey%ic-n_YU z=Yn9`+uQs5W-aEs)ddl(Au3`y@c1-ucjlccpI*N5^2-+|*0qcp)zIFtu%&fTbL+B} z)>W;oYueh@wzscqZ(H5kx~#QnLF3d}O;cwzHuS^W8|S7YnT9#-Q)hQH^tUzif?ztD zrggSV>uK%jZtd!BYoFHHF}JzY)1e)WsZ8&?1GKmYE=jmw{1 zyL|P=Wlmx^fcgB^buMH+F#7VV+k76x`O5G9_#JQrtiy*#Jov)nGN2YX7tizZaLn89 zzQOmBxOm8yXMVYO&W7aq3n$OLbmFb|UVH!JH{q{dJp0P8&%AQ+)BujLBZ7M#W2Z;g zBZN%vF$Uro2MNwNfp~x^m|>uCDpL@8;RrTS&?0Dn9fA_MNpXy&CS}CZE$zGm>gd%1eG!Qg4v6-=qs5Cc0DHC<`~&z~hQ4R@0+M zIk3!%!x%tJj$_D53-9qbhDGbT9dJ_o7i&1*`dQEJ4lH|Q2r~#FJRndcD3S;vlWP)A z@w{GT?~c2s)1rUUT@<9Bl85M!qD6^ei_$I)C-x*94LrIuoKuRjRuOlR3)agmdl!*~ zo`N=|u(@^GxN(hLT?>0Umv(im=xSfp(Y~s)V{J#*8icm?Wvwl9r%s*G*wDuX zj%jUvuB~xS>(trZE%Q2?=X5mAXrDT*qq(Q6jb~uGd)hmvcXstn>*<@;HM6I4){O4i zGka!CYi((qSUY~y=hrX)>5o5Mzm{;!tRq z9Uka?`>l6h=WErV6J7=b_w_J-J)19J^QCLw7K4V1H{4;+Jxo+*ME+{pn)NpxgBF>lC%A`3If`4n6wTr&;ufB~}Tq<}F4M~i9(bL>$@ zu!#ws3;Du8h6q#&$_Ac1VEjxT_)uww&&NcTrC5{sMjv6r1zZY95n%FofMu~cq)&y^ zV+J9+5g^CP#~A(K9UreGfLZ9_PupdO;< zL%_cU2lpz)qn#zedZXoWzX+7Fk%Jw^SRm+}9-}kaRdp3fl(@?6k>lR=j0Xrk?dLAy zjvgn_2|Cdjp0^NJr7qPuMF!s;%2anzgr*{(35s@7FbL-%hY$sI6?%m{H_sY!EHo%( zMWqPzE&c2i4L#jX`-#u|Ee{8=44lUlZ}{DFa6j*i;qhLsi|@RB`Ns9zU*6{@As_tk zJy7PGKmMK%l|V4y7(fiym0O>me(A-8hKlnTobx0n&&Rkmu~9IG>7{51Ap~2AC<~qd zd;lXjS%DjviT%iA2@Zq;W*N3Aj$m1fV~^nRjKN#PfGlAQX@(^-ZnZ%PVFnt&v-W0@ zq`^=L$CR8?1n}iGP##S|Ha`4>e;neL8lj?w#K?uzSfeWi8NC{~gc&vD_UOerltRY9 zd(^);Mjn>V4JJ~|qL_7RoZ(Jy*ACphh1CSP^pxQ&OmZWsphliARpLT~8w3IkQHl5! z0hDM65hBqLOo_ITA()dGa10cmD-DTb`uqDape%mY@L=zTbsW|6vFWR?z4F?{*WZ5k z-P?EXz5n4y(`L-Bu9-Tmcj5HjrPF&>^mec4?pog6xw5MeI=dFNx6Ns6oZi%su9m6& z9WBpwG|ld4>hErz)!8(Y!tFxEuakjeu6}lj>+Zc<*REdy#Bd(NX$sKf)LGu`w3{=PmtQ-}du4dj9q0tk z#T$NkK_x$*goa-pAn7Z8;rwJl`i=TiN7Ac-PaeR@@lyv69o=)}#NPdfcfgOG+V_+g zFrk>A6WuCsf#*cOOMzop*piqdh9~v!nshuPiB|w6CEyYVEjkf}ghR0lNd#qfkU%QP z;ur*{V2(CWLiv1BR{uDTP3~l{EW`;O)3-FmpOB=ftP05`#4a!8t7{;ZBq+0E;1QWZ z6>E=`X~>MV8Uk4rmjnNkg|UR}szzXIfLQisSr8c|T(jWV(*!)`8kA6I5HR5G=wZfM z$P%|~x1dCb9-xR$^n)IIZWBLtf<8&cUQ^m-bZaS#MA_(JoO4H3I=YfA1x4Kz?`D7&l03 zOD&8nZ#=vW7NQ_RRF~IflLi-zj#7xSd5y|?#*9w3V-?U)3Jt-G_{;+)a6WI~9~Y0s z0Ajp2jJa^}HGX#BgG-2xP%2(u#QRm?p!&PL}ytf)CfxiChQK0V-_q}Ft4DwbLVm%)7ja{1HZ&>oTON} zVco_}8x9=Y&kF_Kc=O^r@4o&12k%|JdiDJeKb$*%!T9lYGy4|KoVjTF^d&QTm-bFu z!ZodDF;`E|!mf^4EzQ$fntHifn`U;l^rx$JW>@o!&SoCpO@}djqBM=~B(-<)p;BMZ zG;mCR@3iS%?R`8MGou^+%fJ0kM-J`<$K1Yk{pO9USFV0~>GH?d3*nPbKm7GY-gIyl zjIw9{w%z--?me&_G~;h7@w1T%fEa!%lAp6i-~zjl<;5>F@%xdy7dWAuQwO<@9N&kB za@-3&!%W~~UHa2;vCYVC3ehJdDP?guvIbTMSFmd2C?1`U zCI|ytsJ$}WDq>Sh%^gIxU*jkq^`iG?(O3)jLK~=>tZ+sZ`mrFKtXzZfkc7{?bK>qw zg8gQ_a3*A|1!Nn8D@!5J9w~1I?V%0iVxRj*X|tn+*n~W!fW4IGqA@vSmc0=MBxzfz zk>pY}lzTu9V`NG>X(@}InM^z*)bo*ppE~gMr1aS1u_K(s@Z!5YhYuV-clwPF-sSZ$ z?_a+3_QxL~@NmpGzx(ONgZsc2-idef>xaBihUE1-w_kewHE|5lkt)P7ZWnG}j0Mez zmeT-ZDj{4P5F7zAmK)#+#u7?%g9ls~01lOpldweEKkT?bq1AGC;bai#jpFbb_wd>Y^V7NAK*~ELRU;p(h zZ@+c%&|-1S+!qjHzd)cC%ostIAN^^Y(O8_@ zhoW1M^#-Rb91VR1w^9p+6FShIOg&o}3p?MwjZz90jCSHbCt4mfMCVuHx^1u^W+dTM zX9Gw^7T!WGm9ilBmEW2+WI^_iZi}0H67!awz%gklOYQivBtqPs`cm!oWN>nA1Fgzw zNM&w-jEz*%my+1T%_`en^5{LXC}?|hn;YW+%fJl?6i35M2FDN&6OJKN7l$#t{EknX z4xTv54-p(Yf9B%*?_B=;Cf8N|c)WM_hd=%C$A9|MwfpxtgW(4X_^qYDF&BRQI$@JI zj9aP*9K#mm_C@F05~^nE8fA&8gy#SyL~#jCYEp%;DcU%2xKgr@EcGODA`YlH7&!O| z=ixyC=)hqNB!j)F*l@^*NY3qg-50BxGibv&)$u%Pfx$Mgg)| zQxNtPry#{iVyS`4P!G%p^#&lqijgH^T*N{4#sD#fOQI?f77850$4NwI{uG2jErOUi zbLPyLF#{X}xLL7sxt}O)*tmYv=Jos}Dmdo7cYniCBiCnFKfV9u7wguq{ky;Y`&s?Z z&7QqrR{z3T{m*mt_km#MarO1h?d|F74r-o(?Fkh(j0m^Xcyx~Gc+nDk(82MDIP z5O~73dq!{X^zJUcwFH!DY@GD>Pya`L-tE8t`A>YPbnE7gE0;dKdHovv(&bOzd;i_H z-u?~WAKbiU!?x|4H*HzBZRdsrQ1)-*hy`fEbDw+m?(~3kQp1v5kih(Lx?0>Ku+p` z5hyY9#6_7T0$D);V%WGtX09-em`_eq6d zNtEQWJG1g*vp_~4o}(Z&(9~!%Ny}<%Qe!!8aYC0eTNpdal9aoB&;t^Ef+osR5E)JM zBxX^sZ9qe=8;3j}0vv|tyethEl2YeoAS}O4lReC@Ga|N;0_;^;#DO72Tu% z^HP|V#=?3_`cNWB(Y<(!fpgB7#kAz)g%3mtY(z)ig?;X&^E@xJpZC}uKLU>7w+P<+ z_=AsbT>JFa&CkBL%bR?^`@`?SF@P9kf1?0_i$`Z(dE+A3guqU`WNGlHI)7!e?J%X; zmk{V=n*leP=CO7F3KT&dM$+hxHzRi?XNdp9Aa{~SdTvlZ7zkW~6XQ9q5XW#NgFY(2 zEwYxO)DOvUNLg%BgZc05nd1eBNy3@a{&psPLjUryko~MHikpnaBZPCZg7RL{7_%VE z^3K#aIJp#|T{@?fSxkc<_dU6*vND4nO(bV2BUstj)Bo=L3c?f&SR>41msOOC6&J-_ zap(mxaKjMuBoBWPB8`#*PiYh%EwNh?WQoPV7YL*Rl$k$oLAnYY1BjV5Yu5DX)A@;| zB}*5tT(x5LnpOP1^u|r=01EsxBM;1e^wB$4i!c80-Jknk-rc%w%hOLk&6k^=n=^OL z?0Iu$&7a*ruW!bj8Pof@`ex4V>7LH-Bel16wHH5>gxu2H3J1h=b#%aaRSXyJjPbQG z?X9hRs>Mt2y7<@LJh85(p}vlvAV>)2>g6j}u3Wlw>E_LwpB41}`|rQ<$}5B?VAhtc z8#iuVyLsz+a0yrh@WF+$cxqw?Karh4%=XWR(oTg4|cmG^g!*r(&HiMQ7 zrpStY+5OkukbsI%A`Oi6WRX;Z{7A`xO$ExBE6!kHyO^;IeJpZv{qrUEh#bdYmbWKw zFnY^kqg#{u!3hEyZXamK2qMHyAs0O~aMps1=eQ9{>64zcd)+~(MZy>l=3>BLl}3Rq z$=$~exA8-A+){ho>|h(JLm9Q_1~_-z5isx`wN$1oqy~Yqa2o8qLZGR5@J3KN8xaOi zT8qHL-ifLu{VX}>!w;VAfz*xyLg`06wIkq=EZas?ktq^==ndLV<;QVK**OTh%`J5( zrwaSTN~1aiTVih5=oYR9oA8W7i;zp7Gmd~5CZAJr?}2^qe)PeG*Ixz19OfwDwU^)c z==~4)Tk-bi*T4M2&ysjP=Ift+%Y(g~#E4@!kKy9;rZ?Vwho4yD?16}mLqH7gk6|N{ z=x}Ox^3X60nE6a#Co=*Xg0A?0aBIMpqs)^}mNkasEfy>?gxeC10fIo_7zhvp#{mBn zhqNy;2c9(+5NKc{vBv`(0>|*>^ONWK#lLeW&z%Lw9OW0P3J?RDNT2Z(ZO}PROzH<^ zeqV*{z_+rI?HuccQv|XIx$Yr$DLf~upl#SIo6FD#IRx^-v&iYh*fEP@p}Cq^9ZX#) z^vIZnF)NF4kM)IpZfQYnFpF@;gsB9y^xTEyF$_W0!vf=M3C93s=FOcCj+r-a-gD1A z2ae(KUUAIw70UoItJkd9uyHLvG0njSPs{TC|wHgda=d0=~4sn*U$g{=@0|>PYZB^$&DJN4u%6?kd?5 zl8^*)NFWIW!b(Uu2@nVn-Wy?r_eg;7{>3{XTV2)FyVE^fq-@k1vwV(H1M*c0nvQkf>ETAZTxUc9bCS6rLym~vG# zOf8$vtS6Wbfj_Z$g6{_txfv`97Zc&=9dF$89d|qY&3_~p4cA=Neaw>0>^3jt6v>bl{f*If{pA|hBTpn_4TNHqHp_Dp>v}rVE3~9&j3lF(;p%_NArU3~E8m0-+UQ9mTBQHb@@fQnEu% zDsk8S_uc)=2QItr+FS3v$FC5`U|#bkj`uTNEbqN7CDbxs7B2ufZ_hw<7`BCnMiO3h`EH|W~-;Y?I{d1^K!#t~FJB&lj zp)MU6m<-0SK}UW{VDdG=N9-L5{$xK=78#7spWk`ky}h;6cLOeWR5#x&1Q-ULngFVd zXRpFIGYiBFeyXN6CB>6h>jAZCcDEG-<(AjNOG0`9s zRl6mhE5#&}Uns5*DW)=qT|}oR9CW)=Dq%!Vf{JxS@ z=Io!IRUWh4$6R!-n~ZzzyTfl1^;1Ohm=|Aq{!S{{MAFh`K@mpcG#hZfBT4|zVqE1v*WU0Ic5l4>&O7p$yYIf+nplksFS_8Yv(Gr|r>CEN&Kakl z=?$|V{_v#lA9L(cM;`SZ<2v4_w~zex*S|sk*SwW=l=scPbJ#Zy`|8)e{w1$(9Qw6G z4?Eqe1+gVkmG?hJ-<0H-_@H8JnlM|G37A{h@^ab0_&)))znVN z5DOC4`+Ekkxyxzf@oAXmaVXJzK#`0IS}V(_ts=?w#MgAE8l5!2ikh^x){_##4FC>` zDfXqUQ3SIcLu=c?x!dkN|5IDnt(Xxig1RF*#Cw`;3aTitBVE)>@`EwS5U+L-+T=0T zgvo6UzT$qZ6tmhj&U917P?un_`>g>nv+CBQxu9v7#i^>s?w8P?bl}N0uGwmX5Th@w|UEHv1(TZx7~WpjW^tW z|9#ipe(T-8e#j@1+_*gRhL424gLvf+zuWiD+sj)>|MZV8W27~2{KMau$0+)WJYVTc zgF6ZL6U@@8T45nbbZWH?*a!jh)*+efoH?O!*z^0H>-*)e6N_l)bZ0!GE>fGXb*N8X zBAJlQbRPptVq_$0X-G+(;slCSRU55}5?C#2c|PW@J6*bmduDDEGbYsO>~4#rj;Kv$iQp_n*CqMp~FC2Kl z=RR}r*S>PpG2cD@2j4%*uTh?PhGgUt>v!!n4?O(fzE@v<=EY}UdhNxxe*5ODZ@%)( z3r|1$!gKPNeJ{P_b5g(g?QdUw{q;v4dBldc8XnU*{fr;~=*Or0_>5Cd`2I0RAL~h* zZ+!J@U;4~v5BR%Jf9k-`f97)s9`LEZ`}ik5`O*LQH~;<+T2k`sAlR_Sw&U`ilo0ST^&OuO9pn>t*5OfMA`+w91pmwDfB{ z>B|sp)d%3x5m5lFQxiK4?7Hn2DKdh@!gP{{70XffVhwA%uA&n&16>>6*xwum872Mz z&PL_(MG+bCIw%ia@GTHyauqI==fL^Z;z=I}i3x~vphhhC{qJMAE_hdRl>p)M`J8`b zM!zOS1OkhSmGIKx2G(ku5nMxUYZX=m1y%|N)Y8;~G{Gg1?EYai>rvGVi7KryMV!{w zsv@>PyjX9mJ=(;O_n`KuhP2iD1hN@P^O}jzP;0W)uVNZBM{k*dN!3fWNg7j1W+FzL zy)}i5Fk{Pl*=~ zMQx`E%|W%bHQ)x2uuhX7g;Q*;;92ciSR5TGA_xG*#9&)sD{Z3W!d=2I?zsK&=bwA# zwO5{aX`h=IiOY+>{mo0i|E-ri#vP12#wV4!o{_}7_V<63#3;V`hu=T>{B!Oh+&ws_ z*`(=MXHiHPEF4)4UF%Wpcm&!26gO_M_~3_xPUv+K(5dgJ?!cY{K3{`7_+bJi6L8r~ z2@PD^a)q@RdYZ3^WWwH4a{;p?b9eYok6UF%G8?bfq*f#Wy7Z#r8Yfn5xQVnru=T;2 zs%EDZzS@MXYU>Q=p{@Dw*KV76v=QX9oXjSJ8Pi38F@%;u{nj%t?t9i7N3XpK|L%{!|L6bZfBJv^fBv`s{r~)b{}2E3|M1+)&+mKf zMM=!_FZwp#eNvf!{HK4C%1EQFiFGqyqy5p3Pdnjz$9hRV{`RB);a~roe|6BoU;Ng$ zm&b6t4*TYzuv-~dEJq%7xYu`&{?5_I9Qoa&k2?C8GO8A5)AI zu@^6qca_Hs{eF4O1WG}3FBBaL1XKI2&Q%_R31}Pfsf80zRSYWJ6oBFs zeQIm6g_1R%6_|;qq$YZwRu;BU(yoaV5t~4g#uS>7G^7>nDzUQF_pL*q`SAO@7YnW%>eBDbP^TIoCd%1v-ueglqK1TZDK1Lo> zPU9)yC-=Q@_XGEf@A3uaL38UY1`2e-k)i=)Guh8zW*m%Dn;8&rz~h%I zOiqxtNe&VydswG3>pW&^%Xmg%{4|HFf?et?Zy{~+80)ZnOvz(9nl^lO$06{(rD~6NF(d#g6tL$mMdefxKQ;po5o&;Q#$|JQ&1ufP4{JHPwWZ-4W< zcce0JzWuh>@BZ+I7hinQ{#p%-W112UnTPDeJ47B0cJ(5OIrg|?Bq-lG@(9U_7y790 z9tq1!!Qv2jSyd)?s-*raYz_t+17yBnGk0 zY1aJcl9<0Jk6G`iSWtko@c^A2AmW5Gg>@b?R)R<-PTJPBIAe1yYbLukO8hmD*9u?~ z8|$A~IRta(AzTHHSuy9~5_}0D{wxp^5Q~FF#+~B(+{f^3h5|HMOQNe1IM%@;ofBs@ zOrU->nUFz7apcj{g;r~wswfd|(pIP%JYzF=3j((kvpB8EOg!av*8mc*$kw)9gWC~! z0>{=iwO?&Vt!A5aU31%%@&?lwnlc)wojpzAU>d->Q+-Vr8q!I_bV0Z&AR15dGp|M6 zMj@Tq-dOe83)Xg?g->nr@R)jw6K2Wr*R}cr`fXk<*Bax`s1mN1@r&AOLhW=BvDI*f zQLWlufaru=$zwTF$Keq4fHzg%c zz4prUzj^D~x88XAjn^bG``pU>?j0$M%b4zC-pyk+?=kr#wmil=DL34*JP6_f)8cxG zMS`AK1T2WI^Qnvn9v6!kci2mCrC~--a^N86R#S_Z%s`bQ2LT9Tpj=^OCY5nFgPz(l zn5{fUt%jpyqi^TUnq@rRV4`L7Mw0)l9XxG|9x0h&M3BKZ)UEj%|5jj0ASHu|wcYJ< z`_9WStBPhA1jc6(BzdLo3KfcFRXFQ>=vJqXC6!ipk=)s zk!VCm=bX82Vx07IA0vH{%7hW_W27=b9`n5o9DVfB#~pW^Lw)mMrE`6VPAcPJ+k5W4 z^Z6H^@s84O-g#3J^U7pWXN3AN&IKAO85KfBMh=umAJ^_~-w}|N7tm-~Y!y z{OM26y|C}iH+8I|0=;51gyZxcZ9)IlVXXGxb9(?Rk z51Bpuz58Bz_O-WO`S1U4|MY+SfB*OY@_+fK-@Nnof8D^V zufF==FMsJq%UYPMj6zc4TBVy9mobNY{VNg_9~W13(n-swvCK@a1}_Q8<_mNt$&-Qb zIC?B2j{{b?ExYXUOZ~VvynGK{4MGLiF-ezN#QmQCxWi6X#XlhEgGZ!!38kwaFN>KldM)3KW_DWxqnsXN(6*}Dq8sz3p9LiV1Fa$k zH`BVVFZ7H&x?-E!qFJc61JkpxVpb_<0v!uFLgVO8 z7xXW*bfL6fyUg@P72hc!a{IJO{Q z3;Yn3GQ0`M9+M9>`s!GT=Mk`OZ;C9pz1>ZYE>{?qjaG_R0r-dG9mNKKc7U zyyI(QeE!+Pwr{-k_Tx`K^Y{PxpZ?Q-`KLeqmw)^p|CfLM{XhKSwcot{lBZjqd+x0_ z-+t>i@3@2Uo{>uzDa%tYJTH&AERA3{kaf;VjU5xPf?2#J%kBw-sz$>Qa8iMoHo% zv-88(zDH&gXv77C+AtYoFr&2v2pQ}kJ%}QRhKq4re|_?B0&qYfAd}cSFii|XG=S-D zJ@RPUnkI}Mfs|{Gsdu%89YnVU7CfSTDay=NM#OB_W~VUGH0wyGqq)A|0Wq#tnvCY? zF|BnM4XN&CR2ovENOD?bjj0+7&#;*>r&#;Qn&xX$J5iDVdOT4iz`cq3)0`aGIm;`1?jUj;%f7Sn#9R?w ze%VD=T<#%XU)t+qN>2*hZ@%s(=EdK=)2$3Fed)7H-e5w=V7y-X)9;sT=8wPkR@753 z?(>MNk1X*4o+E>^`US>*PWtSDlPIcFKG-b-YD`1}Y>9$tIU(795QG0}CT>is|l zAb|h~t=`XDr#YD<<20n1g`yr|UDM@8Xy>*2hL`3VHoUr?RA$Cd?SApJt+p{Vo*7B* zZ=H<+7#qA*n>&+PZ$!eFYU9K0S2$14NppF0uEFH;-!az@AT(j&Ip$z4vvrtu=1v~d zDK32hj(izRdCU(tu(^U+&@tYGIrdoi+u#27;fEj2uNOG)oJ}5cp^vP}V_cK`!{7hu z&9~lo>#et5@oSB*ys_`4m-oH$>b_TBdGWPZUiLulOV2#{!jm4$ef;Uid_&#iPd+I% zdDJ&UzWIi1=HVwE_l}Yz#+A$?Pd@eh%db5D@=Lx`kIY^7-+Rw5?|*!WF5zZ1zVx7K=!h@mHmiIX$iCwsP8)V~1D zHrx1OB`ioy@Y)J(69L~ZG7?}$nx|o`t)eO%7Afi#_`=z4!aH$rldQ1piA@MadJ@Ui5!2F!#)xOsGy>I>G>b$*yjeCz+;UJrs zK*l~gDzqY?IaoT{06O`_n%*CXO{|GljI(?+_Pu$`Qr^HQS87Su*mw#w;jK+9^t9LZ zbhd1owB3r1BgxYMupRO=t)&#DTEbM1uI5Jq+tt>jOkl9 zfY9kylUXPPu%7J&N%EG|#?A3F%WmbDYFA%ZTzfv6uEqVqC_+(ihl$ z%yVzQ>6u^eCG}MA%bxlD`#-+&pZ-`Lvs~54Y2JF%PZN0fkpnOhOXH8WLSOgRx?(T} z1IBW=2)i0jiP($th!NHty>_OKb}osi`8b`nd*y3e1^|~#6y;TETk{0AgfZ8g$)COB7^A$W=UmMU;2^;xUTn`$EhaW4{0W?@MA_$-w0?{BGlrKi#~qVw>{r2*k058A%>g#X# z^w6`6TS~W{+Q3Hd3xsV2k!G_l75@a@5bNZaqnAiy5**y-*WQ}zQ*^)8?TY) z-*n@3ZY_Ut;|>0L_QxNW@TSsvXPxb4N#gZ|FMQ$O|Mg$_2)ECD`?{A?Pg}n9<%}~= z_h?HibIy{$ERWB(ZdTG3IL;hu*Z9j^s(;<}xA~#SO%js{Ek9+?4sTvQ^ACR{hny>! zS#d;Z%9^vLm+WQ(MYl#U^s>YoFg_8g9fgNEG!D9GxHgk@_+uYyn5vkH#a2c3v;`Ig zu*G1Gv<@5Qn}D_>rV8Iu!a3++@NZr`UC`?f>(jwIAhN+U7)g$6A}JY6%2!$OM`+hTZyi z|0g;6Bj7DN<-#U=2SgR3GYke$Z3yVg~ilJxgXM<+VB^>gYi?6)m z@}FP#fIm84eo+$h8ZB4L4aPDyj5W3tv)TxL4O%W@!@->9v~8qzP>+PF zJtwQ#_w2LJJ>^FXd`|ndw_cUs+yF0d{6gDi?driiZ8mrT&}$83g5)t*26clrW=1YWRe4D=(FLq*9X-w0!fLt1+C%=^Xj?UY7?B$fy@@0{ zPxy}H+PC-8#0I98T1-WR2qLCT9I1=Fm^@)7HInZ~Xgm7rQP$$c1UGq%-;KIrzj;jK zu?U?Ctsx6;@z*PFBic3iJ-fd9w|=`*lW9KN7l9AZ6%(!)2Tp%+D#P0t;JavX#SIun z#NcW5uJnqkmZ|TJdfO??rp!0}zxJb?E@u(cz_{C%$Blc&uSi&1BWetzeB2X9r|Dex ziv#L0te87joZd&(Ud|}g#28>4de9co%EPmO&9TuESg(0rY@2qL{gO-0cQ<|AwfDH} ze(sqk+{(Q6vLvRLD;cSbWJMmcd;r_iFq=1(U}=qqXI;{#V*dHM4%Jooqi=?`!J_SKhOd&alOy!yrqvKgPm ze(dpIdp-HoW3Xp|d)@4ZCHzdIpPRnTUCK2VU3P)j1(*Enob%7V;F9yb&X-kOa?!ay z7UY|F)m(O&FyR3d-7PuFDW||P2SuZ8@KP~pm^&odj11;WU;5IgKJ}@8^{@VwR0h*0 zjQUpJvLCdU^u^#^CT(69`wgbcF2C66uw1v?xEwL;$2&^P>*ky79ba=0_#4>g%>AGN zNk22`wd67DtYwNrtZUbF@vcx*2XN%C0Ph-%k4*zD1)d;VN2B*kXoQv zEJMU8c%h3aF$ZI2lyKo@j1^Igip~ilYogFISaZT7u(y=}6p&GC{F>BJS<5Ds!Ci8ie$CsI z6H79TX*KX$$?}-3l~;2zS`>GMr%eiuqB2GH)6>w;EjSUYr2FhK(Oa4}Y5A=us6I=9<`QVj?Ze zUipoV9VNAbsj7*kK*XWJ?$|7AXfazfBLuA^CRlHJyNP4J#D()Nx=;#o=R?2x<xO92e;l*6`pRup$z$O3uZx;Y zt7urO=`Js>h(A?0BjFV40#mkq>_$bkFC!F9*ftQP*BaZmix4w1AA%}eRt6%jC24DHg zR}MPppf7&$iw7QfAi`Tn2OoT}DgvMU8!Vlayy zz2UvfoZ7A6RrHzYX7i#&E+aM##l219Bx8sZ_swtu*4j`;pxS8?e*#%WIDzxOAZf{n;du`QEaoO8kXQjlBjzgHe3ae3sG7oT|J)$$nEGmpRWlJAmv;Wux2 z@^|Y#raZ={wcW?~xM_KeR7NibX|m3q4k1G|FdJ>0K-Vm1A^_6`i`iejq%V2*`uMDt z!H+|6r5tM9jVr~>ZPz{yY)@hP zoB6@P+IiQuH?<5nQ-}ElI~ia<`^{tAVaQr!Fw&Pb$ZUW-#%0X$$DQCMiSfe#XM3Xc z?B%0#24l33KmNFnDS2P%u_qst#Qf^lci(!aEa0kJZomGP+isM&xcqkTmnit1ML#|5 zcZ>X1(S?_~efinh=l$fYbI&Y;Ir&E?`4y%go^p~OA2|HTBffRSw|yP(m%j29zg^(l ze*bm@fAcqg^Kbv{zjfF0FaPDg{5SvR-=P2Mul@@0umAPGMtt_OpLJ>U^{;>3unp34 zyVlS`b??#xJ*^x5vfv{0lFBTXF@7kjJjQ*D9nX;3dj67^xqSLFd5q;QHf^o`nxB9j zvRhy_tYVnV@a?XsG_}JYj(BG?h&8vhW$Z?(cmFqYg;|BH4HIN@?}~236su|p=7>UM z%4$;>F?Nhdd7Q8&do`qo59B9>r#yrgeMlJjiEjBSJnlMv?%;3rySE{=$ux5P?kvL9-b=b_CwK8!%)B<$GrS2v*qE((*ecp}wBH?L*VEk-;$qP338DsV_*Y1#K z@wGAoe`bM>%xJi(y?CmMn5lX{ymsg0zcgzlE=g$w(b|F<_WJ=S>*P`_ANW&(-Ie6aN*^bU4Q58@|ee7e(~2Y@AE;6UW$*r z_=0bg@#T0v#N^>$PyY6$GRuR&Z@i|;1HzBK@SNv-FTHwsIL1wj?hMA*=6xlj)fGEg zjB*2+C8H`D6cFI7Q7wK}9nRFpC5Kph<(9jRMvj*L~I>N6(=C@@iomP#!%S|n%RuYWZ^kA%$9!qqbX@SAMX3(&xPMD17SaC!c=isaIcn<*BD1fBdP3 z9(?4Udmgy;hMPUwa_LRCTq}w38_}{Bxr-lG{L$$r|KOw(j{NSok2~SJe#YpCBfojb zH@@r>(VsrxlfLi&V;}z;U;OX)0ermZQ-Al#uYT<-J}-U10SA2MGk&+=b8cU}TjZ`q zn&S5(4?Xly$qM@L!w*05$Rm$C?l^fEY&zD&ykz_rUf_d+%aSktaoHtO5H5ghc@e4{ z1Pk9!USGA`vTWWky2gDBd$89Tj}6q&9@!Cjk7sBIOU|zS`ITNDne`o_Jy@@Pp#%pM zJHl~>S#kDkBu%NUO=XgFFU$9xhHnele?x|AjpRiV85Q+81~{c z&p0(NC?uIGIKC=2lo{!94VYxs`fIfj-}%#O#@4WPy0aR)c?>IjH;LIi=er&rdHP#2 zbPK*-c6%|!wLPrqX@zKKtIa~%Q&oUA8@<=M;;>1^39==4O;r2u`$!G~4|DBJ z)rw8dOCZvT1)#u(lb;d*2ZE#dK2#I!;r*)wY(Eu}8dtCJJ5jdPKKjn`*ZC3noPcr#+ z?mr1f%&8qEhD00XBmsdM;(+9buWBQ;^9T;QJSKOhQ!jBetgX+R5Yw=>b2&s9U^Xxq zOc9}$T4OUpFl#akI79*!+mv=>!brPggC-8VUo?n6Sqq~001vRkG1Od1alDDmj8iZq z*6!2?@|e;W#Hpt)U*;RgW4yebG>5~yyoJcU3k{n=gKBdk-nUK>WL@*@c8c@bA%saJnUPCc=;j5FCP54gTMUwPks7h ze#Xde7T>Z-4u!qmGiS9COSu z-4emzw9`&AM{_qR&S)`3#l$y801`PgGs z!SE5oDF$T<0zR=voy@vf38Kg4T*K8MN92^fIjo$A_a+ zl@eZIpZJwU=T5oJIE-!hU>HdRNzDsPdFJ>hf_@GR5Fk$;v4YnW*MzFZFv_(})mC5B zrhgM>7L?d@8lgGRMa{KZ%PUUrb=@2%ciC?qGb1!e&1ccpi$6Qqb||h5U}*cO3bd7q zv%l!Jwf#*ddiZMtW0Rec*(7rUXb}CuxaMQ?3_b_huR~2O4_XI1p#gN>tJ*J62&RfJ z?-xcOV%-XDoF+StS?%DwRk618Bj8C*D#o9xNmCln2+w5W*NX5ukEv?9n-OZ;P#bNu z7&5?_&%eYM;az^^4cFiG@Pog4=BZyj`}Bj)Ju~>1&ph?WzUTWWlk~-9jGGv*C6#&O zHTlhxu5dPajL&aNV!T=wLu!PEYAy!A60#zOnytd))XW$?{PGx10T?+a8X7^EK#-Cg zHktk6aWtxO)x2-i#vk`YNC@(4xKsl!OQ0c1YH1jZ>EdMT?qtauJ(Y7#Q$6j7$u%jG(<}Yl`IUOHraAAU*^WOd@vK z%l~WN@61|bMwp>8m~3WTX3Hr!_2e;fm&s#xbC~6SKN8uMjCYjW$H3Bv(eFM+Ld}w(lZ99Hk~-+HE->*S}Rh#s1_!mNwp*u>!szx z4>Ens;p6P=$0jOG2#XkBdOu<i%uAmD*S=zdh(cU;$4Yl`hb$*wcstjHQ(KbK&8Z#w|LCw))jf@lEsKR7a=&Txl;{glWNbR7Q)iUxtXya<{rW*NF%)ul9r{jrb z09$zDqwgZMOOCV2a&WbsUeYkN>6w>9Pah&7oKw^<3Sm3ExCq)dp+^WOOL+zf`@z`e)ef!q#=)CBBFyX8i~K24HB4$ z-tBT0mC3;@s_-(H(PC!0g&kg>sb}YCL{+ecwZ+dd;ei_N#RSIt5MUgWUzZJ(F_cNb zQil=_biQAewzO$p#(+soQbHaLB1UI~RD;+WYBH)cB$LkRZliDE(+SE~)D}-7(m%b7 zOtqs}j1K$e*I~cE`1Nmm)%WWD;D>%V@&_lM@&ovcGk@geXQ+Gm zIJD0~`w+D++x0zl{XT#Z@+rec$Y$g&4Nv02{*BoKXpxZOoqrp^Wf?VOlm0mA6lkddiM7*0%c4FOK7BG3dTjvzor zY=LM~3v`j@1ma^RoFt|q8Vo_zIx3;*$MKs06oe->{P>?rY{!Rw_dG(*KWRSn&El37a{!xU@M z;)Ja#BD(co8%Ff(=DG@#8Gtd5cAOG`##dXD#7aq+P_Q&!B{$^R?N~KBR~qvkf}Q70 zoxW?ltNT}IlhS)5I%&GLSe_ehABxyl4L|lKoXtgs3lVX3Kx=+sd=2lU`h(R z6e56#21K+?Cw~TMzF(*p!wZtBQ&o!es%l8^dQ>y(Sx5|y+<5n$cRlj( zJ&!#C-~HGlccLGE6yZwd;TN8J)VoWbhH(euH?chv^U^-|G*TRwF}|JD_s4iXhFQpC zY^Y9~waJzfn^lN@5`lORj^j&j)TTw>hD_+V@mJbSvTE6$ifqTL72bh$_OKmc+ zFLa4+kOh-`4QBQ;W<G z;Evd;-6|%N+GSZ+moXh1u+dwNENSp?5M*kI1~c2yuvW4*#LRSzl5)-Kf>@Gp9KtrE z=!1!)Tn&kGIVts;SS;6M|YGkb_(7FmSC4tU`&84dGR z7^IUhF@TtUM?*x-hevC|uWRvYt*l2^g^6Q2AIt7$y6l>(oorsZn2{938=hUZ`^;uy6e9P} zy0X>bOmV-2CKCr3|CUF5K#>zwn-`B`M)2bDm{Nhkj{l(KAU?Y6L|Zh0@{&@A$zvvs zAOo~b5`UAxEC`LS_v!IN5)^7>F2;Ze*UQq`YE(K+C#GQ+&1Tj$q+y_{O=ww=MT0H7 z?GWC%`D`B!dX59d#4w9Ehyfgu07sM%99TuR5i!P@ld|FLpDiKwo5z&OgqJ+#_+#ZU zU-{~nhStZ|9no5xvvM%v3eM}02of(y^{;VBn0 z*WYlhmk)va6xC(R4{|SeEmE1~*@MjuC51M{Xp6mwreJE)pq)I%^z?0IVM8&dR@nra zLxkGd61!sZ@W8T2yZ0+36UG^VA-0%HvyIrYnya^#jN70)IVM14I^n9wj2MopHNUEL za~4))u{05DyBv#Dn@uC46UGE+d$VlM21W))01D7aR?J)4*D%ghA!s6x7@2Xuyl(J# z;|J$4$(J9{S$7Si&@c*%dekPI{;B=zMCvYs`13yf;rWNK#-;wUa_y}Q~iRBIc( zwu%o!vx-SjSWDX%b8Kmf!%4GZE;J#4VQ0gcadwU#FF@o+`FYL-uOR`PkwJh-BgBzF zH0k`_s_KBRR>QS&l4^@Mh~m+%zIWBehp~tO#4v}L+Cnffgq*`)kU%V+Y^EOfVgdu} z+J=(CbQamS_{+#vV>7$0`C80n@%?#r?zv|P;1^$X;~lr(`{=KIA>N(8e#qZo?>M;+7Z^X{EE62|ON;;_FBT$-61*748NW#Y-WRPij1mIP5%}v= zW^$S}K_DQEzoal5K;zJ}R{mjVqipbS&`7jx0=lDoIvt(WHvZOOjVGY3*U&oKg*M9$ zws(aWbVtB!r6Oix2oPszRRxNzQ?gJHW;1+hW6L|Yn_2r<{z)e-Unc{)lJT^Pw}i@L zzWTK<9eLE@&ik8was96!c~BDLmz92Y{y83e`TmK=pZ23ubggqkMWf@QW?M9?St8_YJ9j!0t8#wrZC~RaSFCMiyoKfV+>R*fEx;8 zFA!Tt>QOX-yUA;q!Y%o=7+Uk4lxp=+j+hp_!vhWq5GK=>D1zO}om?jlfk16~DrRSx z#F(SWk7%uKi)++m*a#8#W>@W ze0%5!0`;tkkT*S6^@g7QJX;WBcRD%ehT3hJYnm< zSi@fkY%haka#;n=;_ADXf&ErpY@X~e}3I<_ucD0 z=JsDbaLX_6zwN-{C{A;9{K1nn)I>f3rftNUL)E&;hoLEH3~*3iwZ*AOY^`m^K%lud*>yl$ zhqxASVw9z}U)F!ZOPdu3R$C~T{Z)*aWVIbY!i8N1MG3)S;)BS*{WIOXHM`AQ85o;q z{2)j0mA>+rQW?J&{mpNE!v)OkciiIF2A+QA33-5bkv!va(#bz$rFt=ptf(;TSa;=p4i2*o()#NY(*v#PNz9CL1KBiif) zYK{i$+H86(yX~1`twuh=F7goWfgowE3qv?Sajg@b&UGH6xhAhC%3Gx z2B5qBGKXL7;5x0xVSX55nb>Y$W5h8lTA3Edd~q5uOeTT$qUFMDmDa1Bm<0zdAcf2J zuku=3zXe+Yip-3?Wuk0w%xoHt1=d$4fhIf+$70zwRs9W+D{*Wv?o+_(#4Q})Y=MX- zgoz7#A^x15h`k^PN)hl8qXE4oxy~@6Cq-CGR+TEf8#zFbNj}YqVIuG)9Gk$qppud) z?w265hO(A5M=LtI{2N@A{+j98NE zs#+O_DF|q@ZZl;>e4z#;unstOr!9*K$JyH4WZKsDw*XQ+vC(r5PUK-NLIkq`8~57( z^D$iDd*9o9lkW-3$AZdZzVzjTz3#p5o?kuq%iHg`&F7Q7k#x$bCwp!eW{pCV!8B&Z z!-@#%8Q5DdNX2wz zFYaKZFJ65c-sWeOHpNTNcTeLbkCDXmRu^J4)Y78rN5rMEFK&aw@=w_zDdxT<%zYB!W*b2Zo2 zc4m%nFdLjC4Ir`N$Qo<1u0q!;X0_y5PZ1|GDiY-~py z4w*oB8gA(s4KoJB$gGLFNZYjfFvPlR6EP_h#6&mWrrF})=)(8`<$DFD)vQttDY4)n zZFVYq$Rt?H0DE{p$m%jY^qA9H9+PHJcQBfAwwhmz)5hV+IN3{%CUU>THl9-czbeazw zc|=Ak^K(J}t~;*3`%X!WROXJyetr9+4}0vlhksqtc)tm~Br%&j#(j+Um9D?#=H8{U zM;3OLTE9BQ(VL^FXwIk@Nyd}S481lawuFx(ZmcaldOW3Kkzs;E&X}L(#nHnrQ<*fP zgM24{+24PTc`&(xR3LirBnQJmBsRUsCxA>w6>a)~r*<@ac!IVOo_>deXbcfE{^@b6 zR-7q7!IsPLa1a))7&W!)?XVFxX!fY$=6rbf4#p{iA*P5AC$x{r~{tn(N;3%{+N5gICRy(A%f z_xocE1@K0IC><$eM{Br!72uYt%9k*ka=mv_`2l)KPd1RAYNJz2!&*s2cq9=NQ1}-?w>xlc z)3(+y`t{YU5#k|07#jidFdB1W8X`Ju4O>Qd9c?VQXd}oJtEU*JDw`!7bp))52}*X~ z(Ke?W+vp5Mh#*A_p@Q*<0ELd?Lk7m<=KFlP0B7MKU;5IQKK}8KAAb1Zx88cIpCj-M zbq5`E5Ia2M^ySusex~&vLvkIne09Jw7lTv8U48_)l47Hd zz)N=F2N`~Hw)AC5#Wp>@o5!r@VCa^kIkfJ3v08w??9yLyA4AxHfDz2hhchE?EoRXb z(QU(49-}J2PlgzHccnIlHulFN*RU+*t~o|;#J8_x3MIBAwP_#^_I5X%ws2Z4ySe*R zFAeET6`4SBmt3+a`ibRZ_==c{oN(i_%NGYvlM!A#_3C#oa>O`Qnx{%}tF|B*f7A3m zZKw7F2(63+kb#?m?&{YFgPB@GEpY5sE(;RiAkvn?)=jI~opx<}GK1b2YPAPzw?$ zX%O84#l4_P-~*2Qb?qbsn7azz)q}!c%P5MWI6!Twh(rW495I{`z*z(Sx)`l(KzSYQ zGM4}2)KJ%(A-pTrP|291WwAaj)G}qo(@y=tsi*kJ(lx)h$(792xBTMDTYhoXtvCPt z?mNA%zyBVuo9@3?1|ze%;oiGp#hc*!?vccJU#Z`__O_Ob7aODt1E{YyNOx_eIL-!& zoMVKAO~%9CCPpzlkliA7g4Zg(F>G!!F2D=;0uC483mna{&G+FP1Oake{EqNW@eckH zj>5$n&v`#bJ|en?=<*541bUJKwWFur*H~2zYlZ%RJVw=iLBBrh1SXZ4Aq~-xbZ733 zr(vK?O)be}6fs++f>=wZVa146SQWyW+k)a%0Sdj2X2qg8X!gb>n_m2307a6DtO949 z$FLl6qmaUo3Kt>+nD4>!mAx4PHWX#NppL^NgRI?w!=r z&!k*m>`JW>E>^TjAexRrGQ5D8F}RW`kNL@&XX%$Q>jLPS!8e$UT=*(Rv3wp!1|P)N zmfA6LbKhB+i!b#=%+5+KKccjgxL8a>0toqy+ZtF-GnX+wjK){N(=;2!7C$Pp_+Lq!)mn_du?Plf6NbJSta!eN7{-tWk zOfT8FiD?*iF(R>bM{Am2@jw`pD#F|>*Nwk!u8JhcKL=||Opghyy?12RM2@|sXWV`* zx#?{ueMw#yjbCy4ZL(8r7PVck13p-fGZ{MZXZ@EA+ko}9bcc(>4mzLmsSkYA&TXW&=lWKrxOIHo7j7tSb3MZdE&C z^%B-sW2iZ-sA_~qNs?+!!CXYunGufkXZdYlyi-p(|3~Qy79_i+<57Y*I#zi z4U(Aa?z-c;d++j!zQ$WlGMjtu!uJf#@)*s%ci(i+UG8J9xb9k)F)m(goGt`zeYI}o zG&uICjV_yE4=jg8WrP`9k!k|{I=)r4M2?Gg{`%r3fETPC1kC}teCITr8^)<>&TmI} z`9Wv-9Os?rbEqfZkzanWh07=4(Gx*KO6tAhU<&mPN1(UVu8V5v2MxI5CWm>?*Tbxp zL{mO@E$d}5418S>BNNfsh=GZL7OfRV42@&ug&NQE69&CcwgIc2s8`)D@{N_HPi zc*!teA*HwhPafk!W%3vnB_J@lfT;(E9d_6O2ORJ({>8t@2<0&(X{asD`ejju*r$G$ zV`!5oAamNU zi1o%y9z&jXRl)4yha?QzKwA++&JUwM07l+g6cJiJbj8*b9>^XO!(5x=$RHM**oCz1 zmbUX4wUU_L`CC3Ywrlsc>hjC3D376S*}xA6I?|NmEebY(20~aqnb$4)H;`Md^Ni?f zH6(zO-wxg@uL?8ah;_rYd_8UkwWC~LhHaXvK46v&1}48HhEpvK2_(}-EQ`DWM0U?A zGIR#EYjp4Vf1Dxi7}&-O-Zj)}V}{4_^9Zid^)Eaiaal(nUM;e~Lns1Kpfe8^HN*%Q zQ#dFh;Lmw1h;&pF1ByZnPBcOhtk3o2Nv!{`l%peWhAQNjA%?NIU6*WgJ|D;4G zo+y<$`Sc&VlDY88D=xbB>I<&E@}i$#>sICpcQd!%e8ugzz>=8q7)i`R+;zwD7>zff zZoTCfciis#W4u4L`|^Q?)4CRh7au z)?<0eG)KH2l(=j%nI)Bpc)vV`Kr%3eI%*j3GS5vhy6y}+zWJIg3|h44f*Y(DZ6z(N z1-A?9Slve8#DwR(ARNRImw=ruhOAFLmQaimSUPa~i%1M9wlJRl)L~A-0;}WlWf(A8 z9`or>fBK^z{iyK58aWsFRKfJ?mn|9IdhhPG!6}TU0byyH+q%gXoo3kl z30thSNzH1G<;BVP3LhgsGW#VotnGek-Rx|hUFto*C6C#>BWQ>087Lm<)V2Y|KMQL~ z8j4nH-&+FM2F3{ydtp~<`Cl!kEe*=Ildo!TTb!CBMt+15P0ci8BAR1WiZcuJOu6a6 z!%VD|sg{PRt)W`$pSjz(#UnScwti-ixw0QHwvkaOBJz_F+pl>KbL|=;4yT0&6bm~1 z8HheYOsUBl7YIb6phK|$QB`pYR^@=~U`9k2P^vc#>I$jMMb}?f3I);^v#KLEm=EwKxCbitB&w!%BXn$-~0O|KLQoUeY6qbyttDPDFfL*1p?r#$fl$ zar-M7o{;!{_Qp!H$zoR#CP!fQhzS~KFuqVN%wIUQWWvea0Y7;|2RS~NbM5ay0ZQ#0zJdvw z*-Rc&=$ObL8t{FggG0$<4nFu`$0Do4)M^40%^jD^NG`d^88q1p!to@%5HFb-KoB-6 zQ7Bj9r+|@DTcD_4=~N?;#GJf&W-o)sY@EhGm4KW=IvYm88Q4@l7^5AF9b#?pLl<;JoMH`J zDud|ig-hqvig~{L2EpfnU{MAW;qdDSL_}{gmgUlA5*NoLm@H(9o0Igrj%{bZ!ycXt zBVv*aMRf9rsYN*QYn}#l9K;6z;Vnp5dLaUa{mCfW!r%DDH@?0BM9iJM=0p6KHhs~l z3u8kZdg!6_Yz<(F1kf|bqvRZtw(oz>mCWfP;e{9cW`1_%<+7P`uDHzWrLJMGw_Adnj5db;-(w?z@&GhF1hN;pI&hO_fI~F5^q$=V`e2=Ra;}fY^(h( zmo1N(92YUMG-KPZy@_?A5bFi(S)AF#iJd?(mXFxW&)2vfU*?_;b;tIc>+6gGfAST6 z&HLayx?Fg4rtOql+{9~QC3|+&W{N={? z+|!H<{pp#G$dBeaHBLkW6IH}{8zBgExE8Xu@Pr+~XC0l2MZ>i6Vi7zW6sPTTrid88 z=5{2n4=hZUkig`-h+>NXvV@G2Po9Xu%z*TQ{mWy%@P#kX$=C!Ot(p;S=7rCSmZR!o z-!->$E7Kp<&ZZ?%xNzsQG6*1Sicw`PybS1wT73ZnK)?H^+DWIJcIxs0Jsg`e?LatRu6PvB(w{VFA(h1vY?Xq!(YTYKiTeFTrb^EgH=emJ!ylIqFMQ3-}TL zS%o0ha1cfC;a5y)G^|J+)o{giulNH50-V{=#yUk+WTpvzyJBOK45tAdY$-Iu%?2%K z+0I=kHQ6ogyf;C(=7baY0Icl?)V2rG-bsPubR@%DVaRrVFlYkEXb9WsEr0uOD+*pg zu?f9bPicxOGHT066pLc(CgmdQ;S~jpJhcRx#Z0y$vD$9c62k!m00L*0ZX$*KTKmaZ zNQOQ}xYwK#$P`B`Vyt>ij7M-2PRo1CTJq$HI~`+uzQm=A7Da!u;J}lRiSf4% zC~FZ%{22rXr7t+nOVIHNqXn8$2WPg!zLX#ij5%}!`HuE#JM4)eG*3gsa4HVgg{m!> zTKq;bgserv0UvV6Az#}Cw3G&OFC@I?m#+xffdS|aof5?K9x-E6Y--Co$n&Ie#~u5< zlTSMBCujcTymLJ(Bbzz*l8ev1{L-^8xyZ{6&GKfGRL1qpwO3zw%~h9Pf8Av_{M-*r z{_L_#eb&ic&T%Jx|CsNc;EgJGJe%EEP)llq?4WRObL}$73|Iva-!qa@nROuDGCbB; ztbw74qAVF5GSUysWY@aRn#@Ch%f*)AkM7AiwMJD zfDslq#0r@N>k=-C8(ia4pZb)ieVtrc6g@>V%@MlT$zwJ*AN?)uNLrGE4X`c{O&ADM z^fP0@he_**85ge%!(do43|Mu>tS^Iy%>@_?g)nV;2k3eUTa%VoJhxD2dt_6HC0W4t zRI-;bdpzUaM}5!rLkU0e^5m~skk_?Yo4&z-j~K@XK+7}>jVQj)2H>=a@IY%?u}Q8u z_=@l&JH^-8#?ZvLCohhJ#sN40k@Koe0F&>hlUlg~x+*w6W{HKALM~D=v6Z## zEfU+xPP7H(B~_KktT}7`x;FiFy<{<)JO(asSt+r?np;)tDX>h8YBgpB6eqG-)vf5H zAtr6>O+l~E4xy&V)A^!ke~UjIaH5cXA4^~rETJR@7D*VA7*YUXU^v1K!~WREJ|>Ll zj;T;czmBNVJo~{kL9h&a^K64_m?bUP{ZKT^0UeaYwB3Za<$eX|-Ka8GqoUJ*$z-3M z(RGBT!~oU@Zh^YvmGX*4%Y>MUr9)e1yJk}~4~*1;`~Kg)0@%^nSI8K-mn6ooK1pu; zexzkL)7H)Kz>>%KZ@rZ3;_!zUmouwH!Df=}2Tn6ITZDN6#JWgkn9HKR7q(j2jAn?S z1SCFm_5rWeOsm>j%^~cZHMO#F;MN+^a<8p$FTL6No%@)f%Ty#Qy*4*77x_vbU+mMT z;qklEV^2$JybEi`7@BX`=4Cr~!;1aJS*&sQ>63B1#HRScL~6%N5#)2!{pyKX@FG0L zIK{8{Tg?>*)r+t5p+bH{zgY5{D~tiaoQmqc(NA7{+cgc zQH7X%#nA{9!(}a{BSKh-MHd@zCptU{2YSG{US87Cp8VAAm(XMlWMm0jxk$;xWG6$6 z7*5&DUYzh=Ofu#)NlAUJH4kS9l4#>>w1drBQsd={#_BK6xcu-3-#h7t%lG5`_(wbV zjML>bE?r=0jo0bto^$5U&O7tmb0j+WBt2wv_;-&w+#6d*9MR2Cc_b`NvX%DKM%#Db z-~m|$Q(+kF1TmQnTXJS(S{Yj=$_QB|nyq#)h)WSg8<-1pSgtuml=%FGvp60)Go0UC z6+MpMaSrFaaKicQmcwG^?{EZ#5{1FV0azY`FMBBe2q#H6`7(^XSSv?bIZDJjN7+lq z*)P^S{rk;hOrdB~U@6$nlv|=%DEx_ITLG$2OqJE9%F4I+ZOR-R_O7tgK~v-@M&Snq z9LB&BV8ucW%!(u~us?p-mBb}O5(GZ_(T}R4Hf=NuWkoX@ih-gcn3)pJzz`rq(on7- zztOglh;?I=I59`F?tpHU%gsVnGJA&_k+BP3yp)d@#JHUcdca-W*pOM zi(n$;2^7eZ#EieCsxD|Kc)@8yq@h2>&?A|`DQ@*%QLVX{h&6!g8jiWOAY_<6td)Kd znR|OQ`(lS}V)m0^gtNEB5jPe)=EP12WUer=ftce3xd!ai=@1fJ0NSxM;LjIysZ4Q4 z`XcBEK!`3{WFh{1ci@$>EP2Z2@Az(Fw(^+%;@{jOEN>EZiPFI-DUoE9e?&OHJN{#? zbB<2;wXoWRt11t`3@UD6k`jx94?g&d8#rhM!%3&2_v}g5M3Jmwc}X%=O{SuDfN*@A zX&7Cfl!K~L9)E^Gn116oow_R_`>JH_u*0MvE>z?i-XZc=t%Sx?FLIg_ZJn>n+hjH_ zY`%BuDJP$K#&S<{)=y+G_?WJ94m;xT<*ls44|j^R7ZEl{4k|;nO(%o#0GgB`akxB^k-!S5=0w7ythwkEs`P4-CLefyKd*?i6hVpNUinz~&3j zI_wQlwIYy`LQ{LO90(gg*gK&{Xxf}Y%LkGbi$AtFu-(O(!j9sE8qtFxF{(f+!F{)aMo40RL0@E;qR11Vhe1KRVwW`d~ z)L?Yx+K@6=oNToo;a0LCS>*B++Sc00m}=uF)=Ou3wwPEnNscs5xF&K)oLq5Tg&ubuv6yS`U5iZ=iA=J` z`gR&B;+Nut&0R8Qoh69&MM7hPdIb2$V~_EMk<7+BM@N6}gk!vabi(raCePEr3vtp9 zRk?|g3@v%qCd(@|Y~`g&X}0fyO$UydjvrRhTt zX?H5H>_L?=EQ!np)XG`_BETN`h`DGXrk2>I#k+SlBd{itS!>o%bG^?{&7$exSdCyN zXs8L`H+?G*tV7c-ZzpOMsR~W)PNB(`1wxYpt23zp1&dLgk7AKX)xKv2g&i@6!2nhy zn-NTaq8P=DJ?Bdy&AN!7EmgEpUX@zrVQlOHtzW{3Ir5g%bM=di{SJULOS%9|&5VM@ z%>0qw-=9}5-&rT;xc0hhye!~EdkfWCX{BF)&^v;L%#spC^lXO(UqmrCYTd_B?mU%a zNn+g4+~}6=#_PTOn3ThGxj;JmC#5px>o0*1o5!qAg?wz%lss+Hj!uzk#~T&fIXKC7 zbSooi%iHx)m<3F+hHc5R3%j80vMc8=mn)i(kF#69^Z(k&&_w}jjUb^pjNj(PSM`3d zi0#Q^b~BjeeWj8c>5Coe#Xf9d27wsBiJ70E>)q}SpYYJcY=2I;#!QNR0K}S~)9%H| z)M}bk9RL3SqQ2mDUz%&O#hlS*=*C}n6-^DN+0B~7#3y4NS`fR_Uaq&YO=lIE8N-_+ zVN7=jwd*`4TKI6N2p{D!&Koo+W$E}4N5qr>9Vj}qL>Z@}1I%CNo7>=EPjkBrbC*Pg2r>ttcIFe(x8^l&s9D@9f7>d_SP4 z^r9@JoCEz~U@I@FNqNQ^$4|ISWs;S3F9d{apmzAv#TI9ZCTMCiYwPBQ#>#gq2HP45 z&CXN6-sU^*SlNu6262SP9KUx$IgPZ&Q#IaHlKOn*YhRPcc-bA>1eaeTXqL)Qm|6so z*GgYl1q>8Bkl2h221HCA!|DK|?KCQ2GG-<%lx6C0foKUkyCEy4Vu4~jh`Tw+Cy&YT zd0fQWTjTJu{7zAAMR*$K>G?JK{bGXDK{6pD0S%x$X7Y@!RD%r3GLj)Gs``ua81ie- z7EB%^O)+Lu6HJ=a8W*x=eaOs$AckItrf3Up<-ul8mUCp{(&ji?&Z9Qbse}NwHRzOV z$3-E=0E#(s+yaZ(0x~De{~vXC!e-l1oq3)QV7uM6t3A7n84Q%$WvFV?-~tpuc_pV*k%sH|{=}sViagQ0vJj?ur#FV#lzCcgH!ImyxhHre3xx-zmkk z;+xS7?pcIm8|F6pBQ)n_PRHj7WhiB@++YN1;TG7U{8?Vx0^-0Hulvs*fAD=*BR~eS zZ|&;rn_f}l;5}{zRJHl6s9rJYn1lZo+cbQr1jqCg@a5ls{%?Lj8BIP53&i+n35cNigxo|!sA;qEMtC1mSr3;HoLDRiHv}D;T*j2dr%4)!3?6x z6qXS^PK6sK+o~ldi`iXwcxv>EP$?@XPUZhoy^q;vF{6!eo`o?Jt5AB%RA<$*z+u{` zcEg5r+?{4+&g{@xMYhMKyRIKJvokDHI1n=_u}k8!=oIY% zN?a;5m9wNIrx`il$Po)i4t;P;uS`3Rfq>zdPkiDNq7XGU%m_Vh#%Bh`$#}AvJvsXO z{eJvcME*mf=Cd2p0bE}F-uJ)bKcfzvC?S=$qP?;knSrzJf@CQiANRm9kd2@AP_K4o zHn0&!XuHhZj!_tE#HeO(=3_Jo6po4i88rU0pSY6w#sBy7pa0_DVJw-w-LrLX5y#kZ zoss=&%dSWB*a>MGHIG!CvO`UK4%oh%T=;`<;LFYvQWzSTGRbVtHJwpNKC!?lBD=}v zq9juiw%5wYzDKH8_VSJ0sV>a}$8GRX~m3u48p-Po&4}r zG7FR;?oG*0B?XcRLwoBfLhWIzrjxR2k4xSJOmdvToRKB0bspd98VMn_R=1bb+B6$A zht-KsnR7aH*22=5D3|8&h?Soxq5L5zD3Sbuq!W~+AmWV~9WT$1eq~xf0a;2&_=rT5 z`N!i6ynSFK)_^Riv?u4ud=eglT6&dNl6T9ZlxrjW+$GGF$>0xZd(Ye@Y?*t{{kx6? zugNcJmiU7L6sqp&Kh4TUtK&PKj67m!?@nldx4-@EKGa7TAGDE>&m3lwqnw&*Q*DHV zbsq&fr~!vhr)e0$?hTZ*|Da5_V#;+YekaRGxhng}|N7g%`!F=)+c5v@WB>4xr#|LZ z&4)_9UgHy`PRfzZ@j*6@tdTozr7@LZ8YMJ?*oM10gl9Yq1~DF%#tw%vLMB@9R0^9y zCEK28HfE1u`J&dutML@h!iiSaIlxK|$Pep3z%0g|9!HVgDl|7fndJ-`VYPvMsdsHyRqf=qMVJg8y?X-%_J*r&ZSy|w|h!*LX5i>2&Vs83FD(K zvogMW8u$i?(PWvnE8G_Bd(-zZh8W7t=2UEDlw@3yki_Qht?3Z%PzF+|I`Czfkc~5I zBOKC+f{3d&ErTrGwUj@? zE=o;F#1XOMh#{B%4PZjaN=gR-F8-CDA}PwJ3Esu!FxN1_mjk!_t!yXN4VC;tD#`&U zt__fCw+PDkkO#bye8(AhNm_~I^-{YO9wku@fROB^_OgDhGzk%A^rz`G&PidasZBZZ zoiPW$WbtPQVN^%|meHCf#@vjf%b#9JQ&kLwo-$1Ob=Rb7y+Ikf4R$EQB9{|!v*LHM z{`PMJG)kyt-JAX0-}#A$L4lYKsEaYBaXPOC489CJn!6cRv47r#XDTcw`(an5B_=01 z$zCk8bR~WkIh7^C)7xEvZjW6#2p>WC-S2o1|B6OVxO-ggc5*${0?zpLxI9Thj$f1z zMuIHBM5G$27Gx%vs9v=e^g&gjnIH>>uqsKy9m*t3ZSGw#dIe(USw*c%!U=cy5#oz` ztxIXU+N;w>*^~B4DKgvYAv-?-N*Y2=O|qM#Eb*y2Uy-UeE|JHf3qDSt8DtX0oCSEV zFHRKnG9Y`9-3oxENCP$|1&?4GtM%nq{J=2~j8BEu|BB=4e?imB-&;RG$?HG)*$;mD zFF#cJg01hSTz`HDKx8nsVq*INCf4Q6@w0AXU<*HOh25|NmHzulPdAw?IqPltW6x7f z$6CJh(idO)vOin-BF6sMne3dVsIJOWxXCyRc!z!|9Ao2}N9D1TtC*_EH9rzlSMIIx zrXIDVeeeZICQL8H3%F_gt%&W+v9C;GeX)4z2PRnl* ziIQVu=!{x@s~(D%FZ4A6`HY+&QI$Z9%NUu=WlRXBQtp%pWlc;J zl^LRt0=R@uLNG828X-O`(q+Tok`o#@VF+oSf{dO%K83y4-UYumy&(@Spw#Xh z*#yEdfAS}P0+8GZW#*w6K!lnSU*Eb1P&63_Kk#LLC}EhVR6+lu-;U>()ofDiBx`1#4Ii z90LKfC3fY_yX+-KGeQ<9y%jl`^btfa7c+%NLa}Z_ACH&-vtrye%H>MqVtM7n6Rmto zISMEJk)LAD#FhqBohTuUgeo8sNJ6>b$(2ZoBoj|au8r&8!7+iA!7+nf_Fsk~gk#dt zw+LqBo?G=4?oQR240-%SFpILf`*2JfW%tnRe2mR6K!spBuStBT^yg&5F(OqsMl8w_ zl){dH!%i59lAUN3+>9>|8ovO@7(At%JEn3;lrO*Hvm`iXKnxt?zxi{ZEx|pzB8`b@}#>nJ`Y} z^UrtaMOwz|EIGXXs4K0cl=7i3m?cmnn}i*jn;sVhGI^Bj=^U%tw_h>OL8TNGRRWX zZ8YI^(FszVgtcCEFCTJ`4-Z43kd!2TJbcthPUBZi-m?k;N=?es(q@gbu37J8OYiz; zHrAOAb~(;}6^=e49`JA2~rhGU>9_{fRUdh zCnXRwA6P&zKEIICE-(GkR0{Ai~hNR5Wn4Hiopff7%8fjM$h-7cC2(Or61x@$-ly z*sKg%96N%_OvqioKUlkd!guh}a*(1z@#U22C5N_*)b z9Dx&YI*!Tlp-ycW)g$|@{5Uv9z89Jh8z@6F3Gs)8piG61E`>Xfh%$yA(Xe>tv04ut zqkQ$1Z$mK9Oh0qVaLH@mef4{36^k#*05Sezh~Ek72TU;|4h%^TsfHhmk^NL+v;sOfuy<*zIVmnyv{& zc+|$N{d=6kC~O7Oi7MBT9aTI^XC35~a_^JDjm=Ff>%7$=A!o;#@2;?#j{CZ-yza#m zWgQ<`{DEUsGoxaJju?>woqQ(wcoc;_luQH}h7(fQtGQ)m@|-z`-%Ik;Fol>~%_PP- z4ZF*0HH{{pCf<@;wXz++ByR_%TzZF2n`sYcKj*yW=*Kiz4x3?POzr_3!w0yTGVH>I z_y*!;d`!78%ke+ggC-ygXG55-Ub=UYijH^e%b(UQKPlxcujAm0WQLI}SMvL-zmndh zIvEsL0aHqT-MEBNl(H;I!X0V=E2^k8Unw`2o~JrFJGsn_4y`{M5P;d$w5k&R(LsAF z9@_Y2=yn8>ojkgy6ZRmCiQqAsMmP#1Il3-|G#jVZldy4=fhzml4m*?p%^;iiyzhN} zA=#(rq0Jnb!wqZGEEeWsT?L0%M1cEVH(#n>?Grn znV1v1LIY?D_sp^&F2*wH>{%JZ!U-o-aslojf(dm+KTMJ5@TAKN5?%l)OeLQ(;a+k~ zL?6ZQXmoP?sq%V3Ks*sTf)Rm|6GnkriaA9XRm!6ilcc+r8D#Ebk`I)bE)CVNgos2H zd7`;Z)WXD{qF>dTth9yidoq0cHqpse@3hA#XC%9cOXax9dXBH8=_tc7g3Hf8}f6c#S>i zUUn?xt>c)^fNLF-dGrfP#5RsUeyX$!?4H@patCv5DEY{lzeGl2O29^q3x@ntpQLA{KC-&S`g^2_Lt?B7O2= z$2clE8hQM5H@K$|(jN~WXQq}yt*JHg{uF#uZCGlEaF>%9s-2-mf7aEiefs97PgN&6 z45K4z$84Gda+C$=PMHM5Hk^AgLW#0EWlq9#xP5mpG0Gx^5{?lsU>7h&ut4~#0T)q2 z_<&$AGK~^^0d9~y)EoBPzQ|R+5F=^zQr?SxDNTASSq5UtqoI}(;XoM-3CPk#i_{yV z#P5)$L@tY?_$k9Km4p=j@DKkmd?3dMSxWYrl28~OLVd|cSeO66(%@(xFv*)O_YvY7 z0Y5{vMy1`ehjzG6*R~I?#0fJ#0 zU=8zdOUGsy4>S`RW=?rZr~d0T)6Ns3rLF zi(mXAW_lT<2knv(_K2n@C{5s6G3%h_JTs@6oThzf_hx5?Np9cJZQ_`a)Ay zq%z@-W2{q^eAGyyc42tchYjvdg)DW-3^dK*wF(MZwz2?Gm!4Q_^7#CrF1$r_;5_-* z1X8`gJZ=wbVt9NQ+B8<*7NxZ5XFdajQ0i^qF~W`hG21v zV~)_VJ}nYHBDn_x#9(BjuuGpGm8IOf^!mOM;F0-OK78N$EJAifrAgJOEI6eci3Y^T zyJ)I|V|Jvn^H9sFDu1KFD6+d8Kh;o9!g4?52EhacR{zKOBu`Qr^G=#4?yYwUcZFO2 zwo7wvfupZV?sm!shCeEIK;t+Z4GF?`SW0IX-y!PgfI=`dF-h>$;23J584P1Ua14TJ zB6h-T!Z8d9F|&0cb9`MU9HV5Aa10V)C4eY&o^4NbC|UWhbmf;L;0LfL-92zO53DfgXSue@}&i2bB{Gn98!GhXO7J z7xxe|TbAZ)D9=9&$G|9fcQAfPR58Y!{{a9@@hm?+bvnL4vp#-$`JcbpU()ltMNO&s z^y@{w1#DXi*I6mPU~Yy8Ka<3u)Y?EM${L*-3eDI?3#?rUl(X22rXZP>=2N6ZN0-iC^Q z!?K5(>WsNhgK&tBIh*{@Wl_gX3={890(LQ@Jdr(|-F7rimPza<+gTH4JnRikXb=&) z-VC^KexU(yfnfM>G@e}Y_{1mH*A$SqA8*FW5R4B3Ko;b!8c9O&5)$%;EmwtI{`#-i zUzR%n%wLuKN{vbhPpT{DRW88tj(13|dRlTzWPzH8935F=gOX2AEfB*OY;7a(2 zpw`dc5qW_Y=h)b%`ddd351XX%)(rpo|EM zS`&fo%xumGZR5U&@t7!rZKiy}>`e&fjo+8M*_yJRTT;QJ#+ZFX39 z7U+Q5e+xl`x?7RWv;_1B$5{WHqWXvaY-@*vLC(xGcJl109y57V9r=l|q}jfG%{!kC z*VVU2cr>PtwT?cft!$5y)6_lvy><3+7_CUJIx1DC^-kvKv2^VFkn@O0#Fsp(V8M%~ zDgCSNy2-%Pr*6Qqh$(d`0P*}{%{c!ssWqmdW{?zAO^h7v zOaau)FU#L>Ody8!FHd-!_I-9V4%D&EF?FnCMYXaz7RVY!dHyNjd$Umr4dQ~&n`MPc zj4&Za$QJm5g_oX4yub(?u3o%1mu$cniO1Co>N5ffNm`mOPxKb9l(dxLn6hAR?GhoT z99h;>23g95677k0K(phRZXNC`Czk^vAj|)C4^30BW~!83R ziY;_#?q1B_xidhA%wEz=%B!CR0hzY@v(~m@qQ5#&cLlYfUb;JZybkR4yE1AJ7 zr^k)_6w1tPB9$drj?$Qo+{6eie?o2yNmK;eLCowSCV8o$Y=SQjDjiS(YG*n-@d~gg zQgv1A#KSQ_3>$!P5yM~-hB7!chdww4+VBH~_+)2&qviOI9wkJYh&`ZeLw9yk6_7HS zL&I-0t-qW*0|r)BSYBVDd5kQIkg_h+dL1Qcgb<9fzL*u{55rp>ue&siq1&-zj;m1Z zd30iQXMPUI4wKMPk|-^zy|s|Hj$`sA8)`>}Iwzx_K*^I=%TH~$NzX~FRo+m$(0X+7 zT;_t&tERpC>`@z}iVV5V@;GmD+jk#LuV$fd`u2C|)RzJ^!hE1|_Y)pcfKWP{c^ja! zE8{&vNlqsZ949QY7-1xN?C!3bQrr8EV{0w4h!i>Yxc#m(51MD~tu3TgC|l7iq$RNL z;LCm=vyA?6YTr5?hs$`JEXFa-k*SWUXhm#~9WqO?zIP5#hR=s%goXh$!Iu+`5h=iz zq6QE%2nG|5SvN2T%{9#67>NqGkCCh37^w?|W0WO1sZqj1^IAW7afdST%G13|S1j`J z$b&McYHBVab{sQcWoH5hC&>x23=Vk9NJ7V7J&u`a$0)-wv$s1F5b0=?;7e!Zyg-xC z2_dx|{d9K9x>J~g?%dhK;M&7FR>3?5$M~d)A$2hml*#s7&md3+F;oP9Ghe!&}*JWDy2CTsgkENk3#N9K@_+~a1d&9)|Ttxh5H)6r}ZhJ+?-x3@MHU2sg;(E2g= z(VeZ%BkZD#F?8qm*2=umblc5+g|~cL(0X*V9&_k;C>uo6TKWM~+Lt!2!B1s--I?8% zbyqeGOgdxVmm}H?y=N&kQHyr>5H%(`V0aNCMATxE)C*6oaKHmm9-bdgHK*mS4PGn0 zY5^tT48`py;+)3WA3?uC>P|DJ(4ff-n|aLa$%Q#?Uk1uxLhiO`XpFdhc7hJn$ttrA zlAMsGp$^@-v(Mr}@2nyM#*1w4H{}DRD1f}^Jaf>~Pp?mrfEWbFNFkzzyduGPSMK&j zzL9l$jh2U^K#a^JKS3?s!6^HDK{AuuWJKu@Q#n-+~P}d#gN4gJbNKJ+#l2!wilIUpgZc?~LZ)!ZCX7 z7zj^JSr?j0UBFhvBz(Zc9s)6;TP1_(YvAmMA@wm+7c=v{85a2Q|w8**xRt2*ulcr1FS-E0B&)@iP1#j;>*8y(8h31sr7oq$o78=;Z$51`;AB zAQVO*6-+b=!o{J!a7;~@okAhOmq8>nbwpvBK|fWMG1M9=rYY^Q&Il&iqO1Zx62gdl z-<)&!I_ib}w$y&w-l39CflJwmI2s3pyYjt zt?36jyH)G7I_COy0QUNP_DAd>)Fe_2Ii%vkc#&%4@K8K8U3TS(8r&5vFFz>$kgfj_ zt?n^1TF;ttIu>H;yN?rJ2-wHO@4}jzY73lwSetWLKh)wU921D)inFD2A{|iY-XUgb zV?U0YBy!>mm>F|m@m<-QYdA*q7ZiBDWFRzzU6ku>_xMxsy#&h~>n-^2*DoRgF%ZmL zy+}3#S=_jkmN4<9t6ss&c`{k~ESMtCMXECBo&`&;_kBWio0Um|AT^c1N9|EQzao{q7Y7_CP3=%T3k6j#k$U;Hu0NAomhb53p{ z!{GP6x*Nnk9P3_1dvcK+|Er*2ZdT?NrdhCNqtnO+M?D=g!|qHQPGUtgo!T#c@e8G0 zwUceEy?t9CW*5=esRPhq`i!@5nDLp;Y^qQNO8DfZF6O!~3E$4nZlsXBCMV&!`kJ;$ z;z=|muSs=wr@lR9?DAno-<}J>I2%9CsoXrncE%ha&z}RBk)8Lnrj!5VQTLTxi&{Zs zoGoQ;c?}UO7Q~M*r=4Nzt4bc#G;w4`7|A}kF6kR*#vCT0vZ8{<_gCM4M7>Dx7(mhdE#ToZ!^jqaEug! z)SUMuMNaigG;td5YH2)N$vZ1i}1jbj<4E2U*1|4d$@G9lp%ACv;Lt zVhAygNjXfK)JT+jM|{eT`-Ec{228_LDw)uMf&F=!^*?Hjfw}PW@g*3I7$p0A>iAoE zKn&_uCLF`0ff(k^;F-OorQ`xaUtv7I;2@lcD+yejsPI+dnJ9!w!byurVnv1Jfin9(XqxDKVubx8P(2D(b{I|I(oo`a9Gy$K36D-VM$~eq0u&0zICMeD zHO$}sKOgkBjQ-}ozyGO^ecXH;r4u*i3CDc>8(%qa%tE(Nk<&K;lcBFPTk|hfB_}l7 zT9X{pfAld3{p9tX<=?v}*RREdW0Z2`LNf>L+tPp}r|0$v<2O%CJT;P(osQEd&)V%n zbh(e=2I|^S4e`m9JEdT!?gS{4X6|gg74G_Yt8UGvj-RDsW=Aj%fU+{iu&SnHZc4(@ znO^PA?1-n}+dIs$X=?}DHO!fggX!L^6Y^VUD-9pJY#bxx?Ui%z!}N#&CA=ugwRUGa z@ea?Jd0Jg46f*MgabOHdO{YOTr3ckI<=%JaDHIMG@HE<;RdZ{q#R79~$#$U4p+nMPSkea@`&M(71JnXDumPuk)+jERPKkdIN3e6}T z-0AG5>6X#4Gu6ep2V|KHq%=0q_{)y@0>9ud%2LG&kw-i%;^mU#m=m4yTt1ugiZ zvFQK)tG|B#-+bVm?|9coKl1mE)!=U6bT`Rf0*{-IZ@Q21_v^m!!Uf0B+~;Ge6NH;~ z(Us22{u69a=lVY}`O|sR5o2jcUk0PZADeM0rn>gTMjcl&m1fn?K3W6TIbLZd%6-`Q zHReH{Lcx}jJ1GZ;kq%h9{cLa7eN6QlR5j!Vc|}`Kh#3jxo#>;LWDctOrb?qVLaS=w%fm!UP2o zVcu_^etLc0EIl9>wqAUt4cNs649EhkL~{Y7+D8C#Pw&(6kjx}MMZI||VtuiB}y*nN)een9Ju%jx03O zeM~Q1J_L8-3_vV;?|a_o=k0&~7yj>ceT^v#>t$|(8;<|#=qqrHzhc*YjIi11Hzkv7 z{ut!wwO$ks1heCqF${h2X!=&YySxII3w$|JEVNiXA;QxKd%IEkUZSwO|_bXF@O8Ff7=tDWMn#n8i$!} zpA&IRKuL(?Nk9zE1I8@eGdO0qggbEzb2{M|pqcHtmGKH5F-vdcELO>M!!fRBKp7^@ zyk)*jJsbnUM8$AXx-fY7%_@XPF2)Tbd?8MCoU}MI{)@?}MAeBjz{rR@b)Nfn)l_r0n{5 zdD+S>h}qJj(;mKrDVa3F!!gdtVTC&dE)cEv#pv-6=elwXHd6VDPS}qObYF3 ze12l;s=K^uI`@^Mzpuwos+NK9%GQ~@1?Xr@e57e~FuHVRZOx2OlahQ_*wqXbEwuy3 zgnwPY>`(^3?CGFrS~@;n#OoI=mO(o>jdqjnE$&u#LMZFibu61&ZeTx-V3rsw4*5W~ZP z7&JHrlo0~T1YU3j2xT~C?qh@uuRiF6W8B1eT~?m%V_+Bg3H6d)b+VT?^0HbPuF{LX z99h2H^XSe`TE$FKmw?|a={sF!oLxArPr}TFO3J4J_v+5;b;U62-*Ai(cAa069~?7- zKRo`O2y*ac2QfHC=D3qWIW_I)8&B@^GXN!%7$adSa#Hs(gJUupDx{pV~Wz^CmIjpKAcM!jK<^mpx8wiGoc1U&YfdUQI50c?^@GQlEfzz z-_of`h=>XrDQi+Kppit>1RuN+@S+nPl8H{msJ)~>lYSF0bJR3?`aCopi?yPeJmnS$ z$IQ>=KBiB@uL_qScKlvpbxZK)mJ_k533C16K`K>`;jqYTG5N@t3IR4-iu6sz#= zB$8yeAdV9h_l!xoC~B%E=>;2(@yBEOKceAUhi)bvF{Z^TqkYcngQV?4rJxMSbT`Q8 zkIiVkk47h^z9*q7d6U80F{6z>`D`*ZO%_ha!tEXqqeN{5A$knQlpE5(?{sv0^tqCz zB$d0SL91fMg&tr^PP))B*A~;%HMQCi&T3Q8r4_2~d!dT-(!IV)5<00RSMIcLUt3%` z7K8Esl|OwdSO;``QtOzUsgpg~4-3h( zGC6^uw@*%s=Hny?Ml9g-Vm*Rjyut!8;0ux%+}I;Y0(tS3IS}|FYW($IuV13}4iw?V z5h+LRIeiI6a&qZ16oQ$wC#97gcU*#(DR&Z{_C&6_)82$1z;T~kE-#&rLS2$q?!e+c z{tfka1^j*E+{&MP4!3=8B{PkEnGfKYX|l=tDV+F@%<;Whsw1>IW*`F{kY=G7rlMpv zATKl%;e$2q{Fq-9piweQChArOK{HI30YCNB`g932XWNjvmw2WwtAX!aKt|*Xz2(ol z`vhn1Q?#5gSdg3u$qn;LaSY|E6Cn$R%^{@He}zuOB{Ro zl8o$jA!}|CoQ3cuc9HY~HaNx!I?zIvgLd?8>==w-!uVM)1y3}BzD`*(>gq`8KE~gV z@yBEQX9Dbj8Hk@VF{eC-c*_K0b|@2nvW^al2*?$-4@oo^|dPNY5m7W zJu2!*2lGgJ!?k5?WsON1b4vTwvrfjkcJui963ae}+x5%^%KY=I-`sHw%^V}|%{}fc zb7nr7@9`^Ygy>HFlTaYgr6{mF_Pm{pGp950A_v}u_`-p{3&I?9!b2W0U3PwiG1KHJ zX4st9lJ3DVv(L8ODXgP8aEzmOpsW#PJRNjZWd_ND!!f{9JYW^jzNbCk{$P8FtvCNELKi`c@p88Zcg*HQE{E8pPhKL^-xj6rU3%uFf9 zI33ZN?e%k|6Vswv&auRcsbmb~gsezFW=N?u`1SDDzq4IIx^-0Q<9lRMwda1S%Z9!|+8Z+q)L(;zN zWom5=Uow<&(!AYJ9SO6}^KR;Q{VnTnf5)#||MM%~{?-C9cj1^^ce%s;q?IT0D6oMO za2gfi5wt;SO40DRQ=X2+m)qyhEAt=**3_}ga$ZZVxspFTi8TNtF*SCG=K8F2s zgzjTx$6orm2`VP@n%$KOq^QKd{8-M5Z(@H^WAq#_wiiNL< zBt@!;P7}CDiXrKzFd*jg%5}XwR;_79n*o3D`VZI7K_hJN=GIe&2M$1)eWk_VgPI-`(fLR$~Bvz zj`Lix94YKzGv-2rQd+@THDy!;bVfA9ri2_8nXN-!&WXFGtC&)X;U@PQNXl`6n4!K zl27+~>HcQPrl69Ua+&|}*=@V9w*9)Hm{FcB#*Ah{+hGKU-8lOW?!D^Rb}PqNG45mF zm~LebY`(5!+{E;=BpdatJob@qJkHh1v%(5M$>Z&hY6XbuGbSOL%hG^IZma}E8g?SZ z!;J1TLLjCX(I6ZiJv>6KsVPm&^vv0W(RaSRei$_4zNI#N$1x75)6a4oF(!M<0t?Ve zA)D(K0w9?6rI_PuF-3U@Mnn+z12NJ7nh%vEiAdV;5-f{AEl5U*T|z7$wmy))xVzyn0?WF|w`dIB6(r~Fj{i~U)rS?x{#A$;S{ z4)ldz!hOePqhd5sz~6T$yW9c21u{ZV=76=AB0y8wtxP2}+{KL2%Qtc{!|Hs@)Wr-C zgS?viBA0taB`5=zhtWZqG9R-K#1E8#V-O#SCPee2Xq=0$-NsBIlw%?eJK?nIAzpI5 z;*}RqzlK>ckV5h!R;_42h-l(PiNel=j-p3GCHX`W@g%h=Ctgj^JH@?5qfhg7y^p6& z_eO3eO|SWz*a}<+jybO0*Dq9FK#X5vIs#g&D2`d6&6#|3n@vhj6sXx}JMSP$kxED7 zjKVQOnX?-l<5f#s^7>SS;V(>ua_86x=Fo)A&?9`V)c0fhf2!C2@_0})oI{*Rc6RIN zuiuXe&|EZ+-!sBfqtj5+H^z!~E4t`dE4$dC%wY))n~shMPdIW+ySkTahmXHNL%+=| z9ZW_Ttn#+2VPEb}RJGZ!K#6L7D)S2aSg&1kMvNJqMlg@od|TGkfR%Jiw{`9oW2xU5mGMwq?{l`ir6D>Alt-P2r&iC@{v2Tbhjmdf!X zpAf)Z3G=R8H-F}S(`A^tkGt*+zG}YRAT!iB^DvrF%5xbrU}#1g{g{#0U1@In^x}(L zZR5VHvr!n^KK9+wXXRtEgbagS<@WP&5)gv~@vdRq!5|Mc$96e)*AQ~8#wG362sF)Me0+Hn{xEYKFXq3#-H6gU^%CHYZr8iLKqaXb! z+XiLe7_aZh=So~aBIFJ-A_ob?C}RfA2+Kw0;xHHEYXTr2EDRO{r^+$8?a6bK(AT#> z&5KU~t*|Bt6etRAqoZ1k5;w$?J(vhY32y_=NYX!*(|TfNw0TMj1t?`?ZkQ&f#7|_7 zDKb;TOh9WZie~spC76k6nB=xg9P0=~v%xWrYz49xUT}`y${eT@XAFW5^I#ai^;^FM z>FTJ95jxEMbDw|qGoStZCtvvDv)}yI*UD2e)O~dMO7E%p z(VrAq+3oW7e$9jFW*(N46&18u!nC#_)Y^o-oL=dtLx`zYNHH9_Ccl0`c>Up73-585 zA$t_#GIa(!agy)!x*Q1Lnc4rIiop#&gHn@G!2s`wS011 zbbOol21+JUoZS0Vr8e(07&IM?c~U-A>znhN*zWKdr46}rmy*wxGLme7S=;2X_^gF# z3Ce*OuzP( zDx(Eu;24$+$9(+bA7|kpJK%mFju~eeC{ySbne(#TiqkzD67TceVrj0*k$113AW$4D zf)(YIg4hJEQzV(lQ}8*po~je;P5~gfBgzxIu9 ze)ah;eEy{`zX-m3{<%+o_SsLo@TJckIA$S$2XKrFm~|O*&}HVAKl-vhYVhkU>#w67 zUlOv+%wS)jrA;2UG*u%}Ky8a^xiSNbr$$*vW%|jdR~vrCF^_&bc%C&(yAkBL8^^TQ zySeME$`f)1JRL)*HcK;usg;p4EdDb@D*E;3JF`bj$P-x?nno_HK zn!5s>q4rTpLMOT%p`o$+hJae>F) zw(d@@Rh9l+#tewr)lPhYMqkrz8n@1Gv9m3+pCgGOx21N{t~&j!0@Eh5govC`6`GYX zpbY;H$9R=lw=u`pVjvhK*7u3hfEdXDxuy4xdwU<#d$25mpc#P!0Wr5YCMXkvk)L|u zK48q{TNjhb2=Ox9WXC7ZrjxUukderrQ1jPN?F}b?!ZDVx8rk7NpggIq2E^;#Gk+P3Mwp%+n3;b{KLPvTLCSn!&lwoTTyQJ;v%6g)c7)IpSToL zWDp`m29gPVJnr2UGUL2(l!>JDZLNPk;IvA)YXhRN1q%<~i0g48C=)4ZdE+WH+Z2 znA&VsRXbkCDR+gP&)Q6{-Auoen+K`l8*?T(57Lw=PkHOrW{f=F^r4-94InO#dzHqX|mYy%%IZFtAwAhHK%5slff zmh4JU&g4|PmFY&^TdA8EDDV0B*ARC6I!r0(bK0xheIpqPd7O6p zO;zWxdhU#jAu$w%aLj1#X1>jy%49x^$DsvpJl$T8e&dYclW~ew^h?@|KnZQ^uOo4;%VNDzmn$SeBqJ-d( zkQ|*Nk~mWonjm&kP`&LnI(Ig$$6VjjjGyvtK%;ZacNKJ$MYf6O3iS* z4jl9JC!T_1zWCDf&wb&u&%gMY7hn239P_Pz`nqq)fF>PZbGRUtDjSY@to8c0UJod9 z{PzOK5FP!DR^C)b_r`>?UR$iLx!L z%P{+B_`SM6g?tuh4l{^xI<_gZU2 z#;!6Or6?d?_YT@8N;{76+6u>bh3yVTXh5#$d%=Zce4A2qIAF{p93yauAYO=-sISEg zb}89}Y2cWFFT==5ff(7V#I~ogJNZ+>D?$D`0EJ)kIh?L=PSxAV2Q_Rjy7M5OTxbNN z?T?tjPlKGEH7IBBE^EQFALcZanMq(Q@VFLyCtC%+889^C116uAx^V>AUCF>PeLn_> ziS}EW5R7utXCaqQ6^g4Cs0kz00`mCg#7q)YG%hxB>Qe*|nhG*SutJuSyy#J@at|!{ zTO3m$S^?+?K~?tzERFkO|zGjUrxs{d+lI$_f&a6yxWMv!Ju8Lp@ zF?M^-LdL}RG6u(>4$jAg4%(ZQDC9C&L}Dbq$!8FUXxKs`9CIZ5S3#CfefksrQvx{V z`4>LtGUiKPc@BtijRCc+3zdT|2lyrP7HJ?m%?w8Sy+op^} z_ZAqVY){f$=5o!>qdEE`p;ND{#nSwI=QY1Fwtl6?S}4qx+E|9FY%A~&;h3@M`Y0Fl zILI0J*Qp@P3B))XJFaO)=tPz2H%MiJnaKt5OA}4Udq;szG&(Z}%;*mzJoQ|qS+(}t>5;TK%6%t?uho`zI*fAc zgjHle*$i{){c^%FlPd)DCMue*+n6V~k2&EOFT1FyQQ%nkn2zdH{EM5l#Z#b?BDr*eHYod%hzrrG5E6y5@F zoF3$u=A`!VDKsnwb{S$DC~Fz)i(yMB98(n!J8;m#2*>((pm!Da7>>`9pAKVO_#5ESgGAGUQ*o~K{cW3 z>>K5y{c_8&rg1|v4&@AKS<7)B6OQRh#yB)BAC0ZzZ7F&K93z*MNT_0tE~_9%Rc-Eg zONUfB4nu98J$(Z)N|JqAvmLFsMdI6zv8UP1*_Jv|J9TV?8E0BCjfQD@xo!%|o_H#2 zHJUC+7YfFiGjI|eMqZr*EA!{dbSg)U=PY1y5FSmhb*x83Xyh3)Ij_r6_b5;xNHU)U zkKgX08>#TpI4j4Wlq<-;{BmoEgTW<3v7lYnru#cc)O*u|2et+97`BGVP=ek zMNLq~pt+ANe7lV0|Hys2w^f1OO^i2JSMh>^YZ!qb@@nfc=J-I zmyC9|&0#AKzkgIrOw0ER8u;Xx2_qPBW1^OTQ(O|PidSM6!jq?lQKfm?OVflb%)~3q zE^ma}ksGsNl}!v2Z>oZrCA7}MZ<5xvx6%>lX4B+|>lUtmC%D=3jsSxO$~Y!R=5r-y z>WGCV2*!I9EGq>0WZWL==zxso2*NSG9|N!Wl5gMh^|{isU-;A)zWCX%f8#61mCWUP zz9zHdm~L6hT!z9p<&`3jJD4>0`J_|owx^(_g}87DEmD*4ci z6Laj?D)yzuTd>v6f-$4h4o>yN+>S}2i;c76#!;vUcfF$&IrED`>|YtmsEE662F6(JJZq#C#&tbP1=+5 zPD%YFDJhO{aKOl?X_veyexJab>iDp-VJQrT*cZD$aTLn&sU@^m0}4;_eH(Xh5WjEx zNN&|gXx_@F`~DOYh)%2CPlSTjB!)Hl=6@RSwmNgrRL9-e*dB!Kj*#6lV=2v7WPo*$ z9ehWiOvDk~$MB5a>^aLg4yKq~DLCg`yo}RLmOXi*5XVFF@ri5?F#KIi;QkXa3IfXH zMLc{#rZ5u7C`JiHLq#N-notpGqLXTrM7hT+k7)4IBN}H0sh84FO0g8xr6$#uV+m;Z z3EhPF_QYP5Ym0BiI+A^RC-Kb@IGVDjgY#DAWz3bEvlf?t7(q!ya^mKruh9&`k%42r@Z#sgF|K4tK$&lT%m18n{eH~#J|++|pEsGgX&ZCJ=MBfKj>qp^ zuPd3Ol^W%Y0gv$0edHL^Q|_Cv20v(xbwvJQ>ZoiFZ9ekVpFTBv?Yj`0zg)cjMoxQM z$MSC}n9*KvjCx9%BNDq77D+pKr&4PU5Rlwae?Bt@h8g$JF`Cw@4doHWp9QyB&6}|G z&w?=&YE`B%)t%V~9C^pkASuiv8tpWbgz0G7r>&~BV`zF=Jfk1)9Sfk4&UgZ~6V+=M zl8kWq)8Au6JP&O$=6p=#@;gd+ zl7uOYev{NRhThK4k+tWx&Y_QaU`VQtpJ!T1-agkbgJuM7FQZ;!4jA){;4Z}bW{k@i z;Q+accO?VLAeZxAYF){IFJgp9;S(h!Ply*$I0m5U^CQgdeT>vH9}sjIQ*wI3yj8j? z?Nyfl_8d8K44T}(C(d1e=SSxanY~whj~n@nK=OYaM1ohU#iu-)F*AYz%Vvjy(cHLZOjWXBzS3QA15w zE9B0KjDWWxzuI7avqqXMtRC}`D#9Gsy% z2=4;KX@exdsK>dd#- zXF#S}Uh5`iN?6BJl;u8Z9bZe^tGcU3rZ>A$%%74%Lsj-rLS4q3Y`cT7v;(Lu5MzNp zVA7?XtZXwUcPt!}NEx=s%G>C`JNf908etB=PaJ?_a3r_A>YL{NtQiMGZbBWuwMFLL zzF>x0bIVrVDvahWld^J}8f}+ox>XzfCN_52v@12uXiaaK_SMQAQnOV?B%{D6QOcNc zm0=R*oa0@q&y~h4d3BD>Iavc<867Q`cN+RAS64)<2@_isef9j>d;JYCTs-!C}6588=RzFva9=ct?k}u znv%8cTl-sK=ec#BM_^9Fku>wxwU>8pQL9dEU;C5rJ<9}Iqb?Xm2v0LqpDrm>lr z{4qVK*l1A&MmuA>CW%bwEBdvi?XYlH#B&e@Isg z8#ZGD#e8L!fGPbYr)JC|{~B{63Ti21Mt?>&V739r_<>-$j8P&T?O~hQ29CL|@5eA@ zWRFnrFpI~x%jK1LI#qRPEIB5hIqBDWdY%XG@@X|cv)pN0{$s4g&$8Fz9>0}&Om(a5 zTNdwG+T&Apws)Aw5=ih3GQ;X?1SdMj?R z77=#MT9vyes}Av4yw>T}AXC{Zu&8W| z`HdZ74j8kFxr_l~I6M-y#cr4C-N&483=re@J6y#J3ce|cLEYV+`A0F z>kz8eeRjs?T=(hjf9Y$W<^~Hc3>x+!T|?cMx8s^m>$_$Fz>a5n2@!yov-2R`(n5BZ9W^yWThzljOQ2*}0c ze5ZIGUjXN5QDHo6Oxcb(diVdRCnco z3kgut{mS5&fgt+`#;p5vp`Ygd&|R%*Opp}uETow$TivW{Uo6d{ecLiIP+pkL9Hyvv z8~2==)BO0yKmPvrzh9VwV?-@)Ur#^%w9qOT8o@L?NSgP@;^3H{{mYNP`n8wBF+NxN z%;%o@+_Rs8Y~08AuI~E$2)J6G5V?SP^wXD4&N!wVcBDm*E66MH89)o1>a6tEPU!3j z5#I<(yw;%xnX==vx*xh|`=K?y5|r_19hvB4kll1I|4$^FUMS`uMxVv+xFiLVgocPD zr1a~Xno{fJDooGb%V{MvIp^A5m}`fPxuw~!*#(TPnZA3M#+fedWBPTOUc-#eY-{>6 zta-Max+q(eCE$k|XCK5kRWZY#B#tV_81!&*r~GH!Y4;++X{|fSxb!e|^h#l#vX3)O z`%DPyWroeaCG6WcazbRs+KoJRj{C%nNswnz42=2hMhL!;>>wr_6NvE|y5GkL0p4c3 zt$Jq#Vh|AH<0P*&$VW&r0orklH{G(@q^_9BXY$JAo0v&LlX8+*eUg$s@Zm!WLt*5( z#tfj$_^Aa`Ml+o$cjb9>lUI)9#5CdCayDT`Xb>fo06?@?%ALWVFvN_5(W;|Mh3>sD zlvn@jpH4}BUrB%HKAks|8)4T`HHVpGi?u~D&AHZ=KfAZ@*nVU?j_IW4fbL}WQ;SzN zc+X0RHw|-8+Cz5hLQ#_Y@P|MA)NvmJ$8dpsL5bk|?qj%2#GBAWb+KBAjtbNh#P&Em zK@Y>DbMT32_c0SU_V^?02pt8e0Sz(AXkt_hVayIh;Fzjit_&!lc^&5b@1PdS1AXwL zSKk?yd=HYAQ)o?IB&49KqgLyhm>EN2bB-vu!r(3Kfzi%8g3h8d@?r+H`1BBn@$okh z1GxgMj)sEK%*TUddY`=bT*-ZmU%hq#q__pu*a?HAzdF?fiuwCWfQyy73=4#TH ze_8pm`h!9(N;Ty;K)vz-LQVKuD^-yZl|6Ve)-7`%j+i1KVgowV9e#^mYBGk9;OX)gn&(Xa>8uQMRo5!W>w6Yb-n5xR6 z!^8-ZTgv5fE!{EvEn*y)N^a0Ncb0~20*#MHc*@f>3o++bZN0OQ);?R&7LEPgp8iNO zO*V7FF;zumFDnA{e4->|^Z9U$XwKE$#|)0?GDbLnV|=Rsf)NzF;`CXPJD3QFK~h?& zqSUpQlg8wj5)5XN(4O9ge-g$Z(p&JQ6j&N-WTn=!T58IgFvE{BCgmP&&O`fTMu^!p zTW`Q(*Kf>9UF_1}n7R;7U#(H&&_v-60Kz8QaA~+ZFx5~+!eHf_Dvk3n&1k9h=)H?a zo1RIUwmI*Ij&Bv1ebZ*&>{8pZAIg14vmeum-v{Xs_x;DW!?UIKjT!r>6pmr)%-&7p z+{g5}62IUhK^ZQ?aSG-S;Ft-~LRo<>zn*drXoaQ;0w-poO6k9tBlwVCg3h!&3 zE_-`?uH?6|ED)N(ARXH=<%#abF#(tCzWv1$;!nf@ItGj;8;#Pz1bxOyCS%<)rsZ6% zd=}q%H{EGUp?#r%X}|UXb(w09-p8zOXdoEZ zFw$7?FW}<(&nz6%6~!QoN&GvrCw>snHnx-NQtRz+4-{euh25camg**#fJ2ki zYMNF})AtD(T_XBd_R+r&3^ETj?N-VpY{CiC1a9o%vD2$)Kc_l7KgO`1V8VyX^iO4{ zNw|*oAW!V{92xLu{_Yojjs0UE`xp@O%rnopkA&u0(I}1 z{4Ng_2FH0%Og>&j+JnO$5b&Z+L1s|P&S(`z|g%n zUz9(+65&q7Qyo5C^2V7l(@eNO)O^A;%|GB$6m6>HEvF@`(noack7c4ZsyMmt=LAL@ zUeGJ<$(T;?AOGrOuWouk=C z24HESG$6)>lXB*H0t4;j8OJOba*z$RcYHuCW^haj_7oF{$sbfP5uVSKfpU`4|HGw2 zHOpB)KK%g-P1;7#Y3uP?#~bHan4!iz^(90zpB~+qX-+xw>7g^Fk*7ITj9E2Q!cibU z9o`s0`V`O%g{R;M$1Bp$Ag1p=<_Pu5&FYTd=>b5~v-UCfp>}!GIHvq)&NKN|t+cl` z&2h|b-!gMp`E$lII0o~CI7V>)$VWcnZPn*WK#a?n_Z)xbPCk~jdIguUCexRnwGLCSW7CesMb$|NPQ07sZZ8pE6@Xp)eEl#I&F@pqOK zY=~_cEF!Ppl3*H5Q@BBSZCMBgf`Czm0u)mnMqI`}f*V(E6rP+hRHNwY=RMpp_l zs)ZT}o}}1Pt{UL7GlOq-w6S9ja0H0?*MI$2<$a`eXmpZ5KLcev0#9-h&ZA9c=GOep zoFsXxYrW(YYQk9N1X#TIS*Wyod$hE}a*#c5^UJV~FC4?I#4ecCam%VSWmTt87++s) zaqsh;SN(Fe&y@fdpDV#JK#Wh9z?%M^@8For?b+$gMwAX7Jq_FXJC`ecKgyTz*5uPN9TB z8C7rujeKbwI#XhJLREd^b>Tt=aY$vd+w3)x4pP-=nV-2S@#9@>bmg>GrRJeC!f8zM z#-xnuiy_=+rFyhq3e{aQ+o!ql^~EQz&nk=_`^QJ z&No^ebz$*!Je3n%VsebVq`wdAxsA{S_NIB_Y|)9aId;;fIfyx$*~4AZ2{N9;+%A8L zl>HQlp9IJ7|9?1s>H0$-`VbuB`rWOpbS2}K%LfOPr6w)O8NkHko)a@^rre{PPZ0LR z^Dtjpq7yTvyoi^p!YfL%3Y1_}10^S1qKdjskbsf&hNR?y7co2F7%Z|YheDJmx^J9t zgI%RRk5Jta!(Js6G`wif$iSMB)@Uk1Ts zGlOFs*_`RaNB=;p5pG+@HZqKvOvYf&(i_|MC9rUe%Sa%mTbV!%K+~s7gJX)uy%43qaFTl=tBn^EcJhFguPp7WWvADV$E&oXBYdqjuFM zPZ}zXIyiC6buuf3U>r1ZKzdQotLFv?-~hi|4Yl}wjNe!4SFc^ngk$K0buh<||G)bD zxe^5<-<~yLvEBKa{LH`OzLo4|ka7$3+#Rf_z9EjWw{VRA1=Cl3fBcgl{q$!)`O%Mm zcxR$9$)2)sjNJ(dVs-*d*8ggC52cwW;L{q0!{jq0hnuV-|G}J6+BESchdMM#ZkI@k zsx|F$lJ$&(W}KKx9b0p0RbR|b&Jv9rpMIq(<^9nqC~rv@%1XPRl~mmiJHF$2pqwsr zhJTo8G&%*5Jc@1Y)r3lF(=_i8)1?PxwOQx>=pNMm*koiYT6^1=@V3kVoK^Odf@)U8 za&{RQE>^ zstI3#6y-nn@tr@%^I!ke&!yvaQ5L9ierDJQm}atuJ*J@~Y00yeglW!72%99v^2sqR zLDkME8)~|!QUDyokxpk$cAe-!`?2mkt3Zr_R%W)hHqK>;>#f@@g2^DqqDCKM1hX=? z=Io==z9J*%!7*rVW%vaLfnW|txfEUldLQ6oVsfE4@0(~G!+#4|e0lOjKCW665(*|9 zO>l@QbW9{647il(m4TSh2_A(H<|bxGEuoO$3#ftcgu$0VGfDpK-~R32|NY;?F?d8_ zm>u8HH3jZOzS6ayOBXGRAgkjB35Bc%Qg-j}}o1%EsSj`4T!d}#)N00^82 z^g!R0Oh3LEjm|-DL(1(1w>~m!xM$qpKTN)@m?8!so0Yt!&zM*nw8I;*^%p{xgmXYNx zpaejXY39mDHPVDijmna%S(Us?q6?|GBzWh$`+4`f{t^SbDF5=^?|JWg-sk5%fB9ZN zOYb0=7!7Y6iygWQd)z&gux0TfYVo6gA4APN%~=L*!e%~ew46WugX8DA*!Axp{lTN3 z%NEf4<9_^g2u;aa%+R#iHoX4vgCO|Gl?)2UgkPW;gok4! z$l~?{TONnTNn`jjr!InxcN0drf6<@_a|#_3TjW|z>EI{j%k@%zuz)Zk2^dG#x6QHp(vnLZyCzfLDu&m@1pwbV1@Pi_lzZn6re&7QiD4l7dV-R}?mmE;$n?67C z<8!5#zVgCXzUH%~Px*Vku4mvIu)viD{gpwEKWevuhV>`r4nVU$oSJDYP2YWZ_40k* zi~KvU24dFVrhDzNt9l9@ahlhstiL*=%j$Iy9Ta9-cS1nScmMgd@4e!8kxZjsO6vbq z3dflC!Z8QX{PB-|^1~ne2#$H}JKtRsJLb0Lxn-ZXWz$n)P89wioE*a$xI|U*QAj=@ zCWcxAQX6Lc$H5@gT9x?~;bgn`Qr(o!^`y`^Jz{sxy~}|>E_W(MP-PZ;HNx{=B_bKd z2{FOW&)$&_Oc~ATxVIYQ*zHHjUiD%b|H=O_8WWzFk_%PMu%@*sO|_L)RUYQ|m`%?T zF#9fbOzliZGdq7`Xhxm;oH(ZA%a97YSrOjbq*z>ZR{Ho~yzUkq56AR9-*Ak}7+11# zywoKf$^@ku*&-@o;0MQqRPHN-I9hd?3^YSYOCBN3c$UP8VkXNbtSS!y7Ut&D0YPeg z2=eZCE=2OK$G)$+K*~Wf7EOeiPfV_j3&-G-|aBg=d4<_i8X(6P{!s2 zV%o7C)@Y*ODb92uj_du3s);CXDYXn^^oO}qe+(%r8e4)_P<Q^w82QF0D;sV zYQanYaKL>aMk@jx;0Xj?;Fb7c2BSb8KmYm9t12lVn&dSNLk+2hW@gx7>ZLUW<4C1t z({#)#$&@3poLOL4Eeu2$d}*Wbs4!~}?dNQ%JrA!qNB1#sjGGw8Et*MH4#;`YX#^m~ zEz9v`-f#KqcK#QFFMst#Q0BQ8KJCZ#3>*V?n3c(_Y;)YH42}sv9MuJJW)8=6Zj#g$ z$1JFEO$w!kNi>-Cl*1}&+6`lM)A2wy`y5PT`&s|T^&L3o$Lnv$1{s@QB2;Oq$WFM?=m~gW$&(HAeyGR@?kpebwzcWY zXo@3Kj`K9~C^V(%vdrzU)aj_YjeTKfQL}sPXH`d|8qL8C)5$ulq5a(PnaUVj2u3*| zMrht~%QYv$;pJj*sbYl~XP+sn4vM*sjw-wBE}M zkI_73j>fhOnsFin`0(wU?v(X2T64kl=)LT@dzn=zQ`?(P9oZ7K6zY{(CLCo7_||JC zCgyw{G#ukK9cqVU!ZAu92B3#ycn2RDe*t2+PXSppE&}Itg-V_{5t0jwRO8pf+!?+m zZcMn?88Jr^MexdwVyQJ_Jq%MUODdVnoZz#_gfjIw~q&wu`lU;KhXc%@cV z@^mWcpoAo+0X-M|U=Oa~o1M;hA>8rIms&RWWv8w&mE5%Qv9yUhx!z zY_*svJUU7sRebQx7&iIA4}MUhA$N9k3}s{c?8XN)KnyhFgQWTYu6@t9zk_GYp1wvu zFoch9jysskMaWUT;Fv;sY3rP)t~drT^7JD`JXR!JPdQT0w9Tq7y^jAA%0vBZ*DwQR z7LM_?7@sRWb{}(Gblr_(j&Iwzj(Xd`jysvbBDby6#7Q_zuCl997@d*lMU$vhCx^vo zLgQoc<7S-AaXM`0IyfeYCTcn!16)4Lnx^qmedBdENW?fgzZm7U_7`|ONZ}( z+U+Tw2at}rlf@746-t~@mz56fT{g?0XgPEUq zyz?(KDd*?yzTE)@{kbpEJfiY$DLKee0+xeML|&6zI63l{VXWPrpx^zS-+S~k8@JtB z%^v>V@BSA*o62KsYLAJI%A@XAE}d)b0#8rE<~BN*ePq=Xlpz({HCyB~?b82G+kFT5 zbzS*^r|lV$MCzOaQUi_9jo1M|BLhrg1VMm7q{JX*5QzXt5DcOyQX-YdqnyKxG_o~8 zn&^>d*7nTK?s&apmtAFh?e)6KyWSda?f$VaduSHNl!+d|QKC(zV3DE|Ps6)dGeXLd%+oBqarULC z2ro~Ot8jr4#;go~hA^WzJCIk&o0iZ?-b|=cPAQ>TMadH7qJt@gluE;tTXRRq4Z3Sg z?mbbwPAffM7(H)XGDaC4VWvbzISK|nb19oKfJ@L!pv*!X;{^?N+}1iA-(2tf_d{s@2O^t{RpEyW|Rj85$mRWy2t$>WZ(8w=2;wT18$+Q`7P^ zzBtYzEH~AZgjYy2Ro>Z-eNPkNwg^p)Cjg{hNZ94y{SFLrcxoDW|r_OO1;7|G)?8?iW(hc#Nikd$#X_0 zK=?@m&pc~Zk~!2u|k04xZO$vz6cY^VgUkc0{-DF`M&Bx=HiI3}726%q)t z5XWfDLf{fLVQQaOh`Vc2ZY^POTe>2*ABn!wZ@St*z%f(xb0tvKKp#AK&{)K58i;f_ z9OIFS&6Vn8%zgLlnwbV-ysy;6F>+lVpc*J#5yt=o#iSeY=5WtFjk+q1X*!pTdzu${ z6U0=KS+Fv@0aF?ijFnW+l`1GxPZB*A93v{Xl4t$iWgPSHqaXgDtHLqxMA>x|{rM@* zhJ%TlkukpKY9$mLW93ALJ}PS|{!A2Q*f50n_&j55r3F<83yz8Nqt>L7B}=q~QEnEM z<(dMUtJjDo={-U-0HuF1(acnsm;GJyV|GBU{GZ8}`B!EJCPLwr^VER4Zp*vAHpwjaZk!!dT+;TRuX;OQBC?jgQ}_X=Ij|M8AIP}Aqpk1{46MW{4X7!Ij;qxd}g zB4tY^IL0rkAed~!2sMv+BDd*M?Z>QJwPtkX>NSBcRk(b`;N@3->UVzztHZVRa~$>6 z{*PC~6z^EOxhhCAq8uHafTF48p>iXMmU2W3-((i%QbN_G^)Ab7SjGPfQyGFZSm`9q zk(zDBRjN&{W?qWr9xRvlv?|!8goLRMqXf6$zM9yj++9*do42o902+OzGxem)+T zMXfLq3Ns!l5U(y_@JEsoo#)=N%!)fSu1HkIdAVqYigJ^Ylq`fwFw$9{LQ9uW$OlI* z43B9NWfah0RyCLRLLXl;CQBx3(-vHfr@4@>rkuv43OdOcWfQA8pECbS$!WZ3=3hxo z-ex(Gq@r@0xjVh2>T;)|v4hQ?4`2GfjB?}|lzQr21~Dd&8D(nCgEGzi80I^hF|0Wp z{Q>1D) zW{wJufo7z}2}$IWpp(I&zQN(%fuWw>{?4A>&fdN*7pAATyLolZz2K7eXsTwQM1>>~ z<`&Zaa{KNsnwTJi>}q85Ad-YtN7Tw;2*c1UC6K5~v`YQ2k7LrF++FG=DGf{W-aCx4 zFih#F^kG86BG34iIY6QGYK?6!2Te`c%Rr>B(nS#}Bnl-dOe$55LIYMzDhx@oq-v5( zHuKGlf`g%9PaHTo(;k5`K`=ox*^jYOP|%E}WI-{!R@oKpt+i<})|T~hP!=_2o_S#$ z;>MVlg(PX-eoQb;K`q6XN5cK1xUPa@UBj6W{{GAZig7 zwG=1}E=kp*$yHM2B}uN7kQ$>)GiO4_k5|7YGt(Gl#5!B;K`_~j$*)po z-H#Y3Ar6KQ;0!_>28#2D+vA(F4I@gY=`i9*NMuR&q>56m3aWp~7aRk@WcQ`u7)&TQ zMi^j2NRxi$t_J(zn4#e+?CXCQa8ao$QngUC%brKYcXk#Cl6xVn8+AF0D7Wnfi$Zb< z$-RMy zM3a>16r7PTu%loO3UVd8u+)_nDkKzngy~)q`m!quv;|WtfIB#t8dFq~$V285C+868 z%*+hn4#b%Je#AF%jMb54lF)jwf*9rCm|}Q~LAC%xS*j(htk~SolGqAHpy{h-T@SwBMJDRP&Da?%B6(pCz_fGMWcgJNC7LkixQGcEm5~wHfAuoNT>^$S!T@>LqEo* zrlxG)LZ~dKfio!V?X3B&zvpX@gfD;o+-X04{F!U7EH$4i*|gyPb8J?aKU6gD{h%5Q zRYz@tW9-M^Yq(IMgk0}_!|3u^mh6!Pj=(o5qzHpN%JeX2LeWnc5CdkFD|5z6*JqzU z<9gx63vkT2^Upi^OUDLMy@yn_tuXk@`!S}tIUOHUCU@{8CY2j9D5(GSBBpYI;Y@FS#&Teqrb|)shrpK#XNs9JBc$Nk*Y{E83)m5~=1> zvd;_2m0Yd<1?9vLTrK0ga!T7U!4R3j3)NC%X>iJqvW#X=nM{~WCUT^xDC3)I_)<%) zc==&gGnd;*rG?2|>)z%-;LFg2H=qcg0g{SHObld_m@}qRW>gqZ#vC)*LcuW%w>2-c zD`T~@=GMR8sSpDgs#eDHTpqMQW+wOI>3nsar0TU6wRV%avn>geg6iDumI`h(~C= zjG94*Dp1f&7)dl!NWxT_779~ZicK3z5{6uMh13OCCBrMiG*43*!6 z?SQ*!kD55fW(=}MgmWwAp4j17;9_ROSbAB53A1<;79$p$nf13vUm_s!`?~U`KLbpwjEr5S;>Bkr%MjX9KZLdH?b)I3fzAIG4^1ZI7TY`;mQt2 zeQef8>K+vhN(h1}IA-?IQe!uzfRYrVRTv?83NLfxGV|_T8E_{p)X3_p32N~;34(d? z;tN2`JRFm@HCuR1T!qQ))4j8B-~+S!F`450N@1uqK}npAbz;H%oH$07vXClQR{u0t zMJN>sMdR3_gD*=fym2igsi+z0P)Ws*Bs)elzBXuFwyp&TyVWP&b6a>vWkm~PWQ1Afl2{uSAQl5&DK4tu82%XF zJjdDuG3C(`?82SLi{p8B#MKj)DCiIj0Wshq1`G^Ai0}wQg2G1!hTB{cm1ac9)>Ei=P?h#R5)Yq zt$0lE2lx_f1h~wi1b>EU?k_PB!Z9_JsSfHE9z$6P*^j|AaZLP(8KM?sVuWV-c_60R zG^!qf32n)oIeYSj7d=-3XiobROYU^8u4-4Nz%R|NaE!^VkARqhV?+y?_f4KMzfwr{ zpA*LQ7Fr-xyJCQz>zp_(a42m9mb6}2CQ`eqb6;U}uTCywv5=7(l4N|Fe3@fmOolSYFqt;OLV+^o9>bme zn4I&q8RHiWco8_#^eFKwTmq8XBp#v&G5kkdUBXg`X#7n)ik%gBr68CvB-wP~a;Syk zeo|wpXts)X;2hzrZmB8lFMQO}tJKv6_$n%eV44#NjxoFOulwmffsQaN~sBAA}03 zdUWUkqAh2`k#1*i^*r(b2wd>-m&+PZF>?=E4cn-L!a7-?hDqN-UmDO`4y=HO;$1FrM z)!c6oWh7U~3i+$z7+K_1WLZ(AcoM5im{fdojTN_Nu{B{q+-FjSS&GG}H&dH9rYID6 zF^@5INJ>S8iCT%8QU!M4=jEDLW}?MLG&2@{AyZA;+G+$n;G=^{b!lh0qbNi<1}Ii0 z&?FOU9!$BSaGp-du1us2YEM6eY2uhN99LtEY@sp}Vp}r-=1ntmCgwQI)o_f(?;%dX zG28&(5I+(pF^eqbo(ph4h@U`VWZ|NcOBi=m3Q-h=Y_zDQ31T1^l*dMKhYG|5#Ka4V zrXoqHrCD;?Ddg1BY|)aX*LU}H^z?P~^>wtjEb44s+|{Kyb?-|+H*6)T6li|);H zZ3|K~3V9d3dYNmm*D)h%-c+ZSx4rVdIw)grX4$f3OP4Oa{`%{$z4qG0ix+FEdocNYiGOsiy6DIPMmLW^1*iZ^7qoay>BneRynkVkAl!+;` zh};bKveM+_!&*~n?s zbs6A-wkk3cu0RbOW8Vd2abfJoTzu)m`4`TdJ$Dj_A)MP)s?H|EF@RTS_PG+=P(7P* zKBm4h(GyClkjqtwQ!%qmYhhLk$$L=IQC{FnsjK*~NJRO$<{HCWWLXBMX%zS&~Fjs3>Q_&vxhB$=RZYDVmrfpO>p-e-EYx53>M*ni5Lk z%^M+5LZ$N04hPsF3d-^7vNxfcF_lR(8u5GE;1T==Z> znfotJC^2e094a_Qb@8l(DL=KBDoSHgh3e2;*_UBfadkXdkO5bxJqXi;9a4)IBri#X zl9H+rq)ZisNg?5zI(Q|JmsY8a;;d=ziN5^x{>AUR}Zfq>RmP1Gcw%g!jG;TTrFwMiuG&#@t~FK)~#AKGVFEq z4I4+-Z&JJpu^+WHH~Ye!d)t{b67*=Lc*#y7esZ`;0g>$WW$ z$2JgN&f>Glqq0?CS5a=wJqq26kesHY;trsAaARYiFQK0^+R@h`dLSK}&XExlN}r_n z!j~|)^jjIbd5omY0Yxbjm5#+A-D{57an!=8sVUy>rkiepW6-?)7&f`Am#iaeD!&h7 zV1-Q^o3&}d#+X>q#YSO}g->WzD%oO;k%`?X)`O90dZ~aIVT71j2veh$Y`2sLEAw!S zDA$fES6>sXfPje#L|nQAPXt&H!Us?VB9E{rBQHsA2SZX?qMdG8pGY+phYlSw_w2fvd+eLuW-W~lMsHU} zxPFcUF`U0}_7iWvIX1rj*u6*Kn4`yU_a~NuV|?eALJq_P0SIk%AcgosZWG6V1(YiU zQ*Xxj`$xH86d=YoT7qK&UxHwQX(EARWXvCc41-sor&_9eFA!sLGbxv+rr={7wAPH72DU{Ml_7*y6tXIFK^YF($5MVB#W-Xz)jt zgpizHNov#a{G7ZJvYg`8O4Xu>w~NCIZ-C26EBL^|BNr7$zc8YBR6IQ<&J`0X0kM`}XaFV}dGp0=|R`DGr!~$K?t5gMwqiG`&vr=Y?@v)KW-XwTkS=2)UM0 zY$=&$NE?z}*lbUPc?go{Ahr$cVdQKq{)$%xAG$81lN!TR+bRfe*J073MRpy8*Ijqr zFZ{wU*n6;XlHCX!5*S+%Bs{2lbVtGz7Z3b}gdVAZp zZ98`Cn3-O<2+r}oR#`n!k-E?60jeB

wYz590^Jhabs=A+ln{U2Z3m4)Tw^=MR2E}6Qg!DtA zS#-kKRVz1UEyl!Rj~ytCXp)$MP)rS;iQuscjwv8!A&!Z|hG2qJ0%ZbgNJN8a;_rn~ zi{rnzfS>^sR3S_{oIwa2q!!FPgrQgxI`hg)EwUp?QBZ7%kfi9;*r|HLMKZ5^5=40+ z<-Qc2Dul1T`l{@jis%~x2-SX!^#!l9a=Moe>4}HS1;qGZ?!%8hhyhuE z8-PY?!hD7|OI>37ZDM~>ci@BI%w_`!!Bc#zNVB6W~Trn^v-y!r`z zyaFpFwX6!M^)jhY&U+9Ysj?$XvIv#KlNlsy36o;u+k!%pB$e}Pf|#=8FyzLb0yX-f z!Y9@8i`S<{L9S5NZ8Ib<(dd*_9WS26oC3=_FG+=oS}GOJD9ll9>A)sK$5;f! z2+MHKjac=6hF+L?(wtFDb8w8Qh^b-BERL}s!`X0bRz6$L`|=qmzJzbU=htm82j9T2 zkOX!#H7UzgG8P_F=?_(|h4YJ>$EZu01shfVYG8H`qZH0{A>ON5Y$}>P!CD_sb=1Ry zn3mRMt!*vKT9zhUwD@|LD0vmOw7@G$OPdv_LQMiS>{al`n#9lfB?o6PfLTHA6>h7d~Dm6&A z6d;O>Bx4)aZ{NCQa{D%=;b~R{t{YvmYIuCZTKg-THmzH?VPxg%p>^w5tQ{HLFuHu} z#2aNRDb?>x$hvmNVL+Qta3j#W87&Ns3k~C2$YyA5SS8_xp~W`-Fs%h zufvBAg9R80LOXn-g!^l{<(6ASg?tPQp@;2@mum?!cdTnjC1PM|Ds8aT&Pl2*mMb{`~Vbk zl@`fd!L$F%8&WJyB%0D_XiVzG6DmijNl1bE`M`k#`JG^(jh((_8;y}9!=blx7{zfG z+Y(&<`)|Doj`1Bl2i!%!RXf@CClHB}3CK!!b6ND(qF$HFwxx&Gk&9{_I5{=g0)*HVZADycFS1x(?ygp33#I#Gy@5|HI& zoGd40mZe3~B%aSeUeQfjf#gz)zM@c~!4Pq%G>ae2(w&zYA+_k2T*^mr;X-^e*5b>1 zu;y7P@={3h76dS-^Lvkr(s*^*(V zvmcX(N-Q|4l53nenp7Y=gf;{*Gm?N%*5b-WF<9oOtguhJQfXRkRZ?|V9 zTqeiqatOl}zoO)-AP{Hy5D?=n8@$WOj2zCe>7qa-2ZE$Pp-mJ*Oez)fYW7QnT$+$V zGUCJ7(($kXcyc4^<jJS1AXdSJz1&ro;A%E7*& z-kt$WU;E1bw$%fjecj6(d0D=^ueWRIK=;z2fwrNZ*5%#p!(DCF)!Q-L+cq-THPp4N zxApqYw(C3Eu3y%=sI6nEchQ$Ez5crEuXO=%5FTLX+cWm7L@~L7{FW|TvUtfNS9Y81 zJRy5g*_tX*5@htv0lf|RZQe4r|G=KRj#PU#;L60r#P)3yn>TG4+X&ZaExVQu`s!@u?b^ZtuOZ0f)Ykz^)VwB zau#XUX)H-BPi0N!h^+`Q2(bo<(j;M3YBN&>1;luk6dV(LL!RxH0$;);tUP&r9#%BS z1A+;0{Jeh9fG{{943r=W0R%2Yr<4;Y6U3lQ@)AN1GRlSUfJO*STr(lkSbV9|{uZ~}H<1Kd_ zJ$nD~;}3!|_ul`2%Mo1j8-3`32jLjA-ZH4Y$-8!3vJ9vdWK$UWC{Yk1{c z8PZgm1*SAicv0gQAd)ZxSsdp=#%iQPxjFD8)+8$WS+4W&N>M28w$3yg$XlXTbWsi? z%rc)_CCxUcRps{6OA)5GOJ}CfBQzozpc0lL%N(dCUp*5{j51F$ix_BBa16tp z=Sr;kjW^!txd0PyLjt^D{kZ{z;Q&aocfzR<)-Gl?C~kv0L82kaH2Zq1BQ*dDN7e6? zNUsl*bkt!NccpO3Toi^6fwRaeeJ9ITGtG9FYjx2w03x)V`QjvxMvyk;IM69XWL*;Cp-aXtmyAp zRbPO}@}Ab=?iLq@rmK?lwneg{x2?LQb}t?7S~4=wzN)uvWp_J_GSc6%Zm@lA|1zO^ z2YWk)`n#6*wyf@N9jcXAbS_)fxlCAP?^?F1r)6d5lHrcU{T++Io$l_|_ReM9U2Scx zOR@_EvgFio9=ZWE7{Y)XIxakkzRe>xVK7Z_p{Ucx`dsMY8hm3QW_Ito=h%@$H|!hV zv;j8F=nM}nUtx=9<(d`CR}T&hxo83$LZfWI$2Je|VzTYqyZ`9j)nO5jHQ`7bKTZO9 z(<*2t!)*!$HpyEio{FleRTBm&d~V*&;pTcTM=libZ4QUBA7f+5JW+K(%++v=6{Lm2 zrkS;y2k^<;F{p{m#k0(d=TD-Om zlnCn!Cb%Cisi4fGkJ>GG_=69*V0y1asTzo(>>`0+D!AisKRy0X5^Udwcm0#mk;ZHw#&4EL=9yxOF-FM%2^!NkE z?tegIt5=C?RPnH>j(OlRj>&q^t;njV-OX%JXPP|`9EF5{OMDMMgb|iPFriYKLbBK} z&6U=~G0i0xzgS%6JRFmO7iMJ^<>Fk61XEUT;Uj5=(I>$)n^E#MeY^>mXi$Z)nR-RO zSc-Y3K{Vii0%IYHAxSgTKCg;IsTBxoLzbsy&+( z)oV2h=L=J^P39UE*N?OTc;=~}X`w{2Z-``Yf7O@nRYgDv9&t?T-iDIADd)7P@5XYtye zWux6oH}tfOb+@kXZo!OpE?L*Lbc3s>Wli@|xM!%py{D(m%h;eyz)Ii?q=Ip5NEjRg z(71q@AR7(GfiFTxQD|s%K1slh;Wngjz~LJX9l84s$7>7_@L>?ExzSa9+%ITm z<%(4!tE<20DG8hnqJ?;jo##s1wr;=qrdyabk2Rg$@xaaj9UD9Vjn}3!k&L@01?&dU z7=45fBg~v!h+`yG6Kk&O%;apsm8qg?vjyZukS?-S*|fBCR(AGCK$h4%5R;`U%-V0R z@nT!%G3>(?O+@TTu{LqfaZzzayiwenq!39k$GlLgj1Ua(F67J#fGA8bL?DHbX0wpM z2*St}A~ixGp)5+kCl{tj@RGn6RKQB9NRsSyQfA7}?UX7AL)1c|nDl^7DE&|vsVps@ z1-|%62FLhSV?de5xHFbtw+F}6M|~gh?8fC$j^{fSjyZOx%@_<=1IGX*pv*HTo(Nd+ zXr_KTQ+*rPRRbCiXr6TXgbq#nF%^h;=w5&8zy-KKDqf7Lt_FFY1*u5NNAsk@F5V%+ zXq8(qTeui^dh*Pvr=ETKai6hKqeoiLd82xk!6!^5_)zV^JNg zKW5NeT~bS#rKnjLf^D?5^N>o53jPg}P9tozjfjqSfQ%j;zrXLE1E$}4_ zR2xQWDw0bf!qR}b0%q}(B((5$QfcJrqSC_jl`ws1L@dj|mu5&9BRe<#vzv3KhuIPw zYziUMDJEO!$0*|RgJb+u%`+F)KR|>N3I*RRbQ|#>d>dDXI36B|Yl#=BotIze6&8VD z;24)J8QTLqpH!OhReYq=8xC7cOm5viv4wYpHnwct>{_>el;czpP3KrV`JSAdgi+j! zRiG2NqUq^ra_t`(ss4J7Py@6i{+KWHsxxoBc-fNcmtMDI>0*vtnD49zy`|jQ-RgB^ zSFiV(J6e66WqEH`f9KMn9uQ>l+QG$Z`j@~i!(G>{=(=`I?{#Z>esSY)>qy_?6+Mff zla)R1TQhL|>VC)um{_s~H0fWqc3>$WGTOhywWfE`XwRZ`eb=w+T`b(#zjVBR=~(yT z^&Qu3=vg#2uxz|<*`~g>b?r+wb}!pL&@#2Wb?ZROSbxjtK-)-P+xp&?b=`|M4J_N- zw{&W-b+T{SL|@C~K+Cq?CENR!x+Vr&DX+C>)6?n}d}GE(^RnXt%>=jzffb!k5{N?~ zIy$EUIvv$EOcTchzK|pRDb%-~$e2_&-gJYLG~U)$lwx&w1vq;9!Iw27Ydulgx@Ft+ z)DDQp=-B<@SB$Swt^m#OFikr*1`9b~49eJJcinyTh_lB0kSS;2G{98MgcN3Kk)W&1 zM)O2Vq()73GJ@2Z$*R*5dqN=Z?YG|^5cA$R#?8iDm&IkRnRqdhS(wF?U2Sz23qv9H zVPRMd%PdH#pCZNI6iH!fS3dj3brXMtj~bxB{qu-{EO<=NMkK)&5lRh=NC{wpD&$p2 zD5>P4g)hn}To`3)DZCUL1$AMh%BXx{vgF=XR|=#PwMY_D$c+ngk70m62ARDz5Pq?k zKYrUdD8tGbCWFOm29`bF`fYdF4g&%<99W2Otl~L%!k30tKgXGcnSfVJ*VF4jq9i8 zPWH_CuWQD)?AU+k*1L~AaO}PZ?Z*ViWUkwfsT|G+Dt8iqf+_q$@KKVinGhSz{qQ;= zR(s)drMk%3Cs~$OC=I|j{ajYv6>*F%Hui>DYKEM0ah7_&cvgJeYKEj4W*HZETaudk zbV^;(jHJ23n^u54)D&KkZ>rT$p$eD@${49C5;cTE67n=S3YB)PFHBJw%7wB>veHUe z_VlccXvQ$%Q*3H%CZ%?TQ%FS#OJm4O*BOpbvsX#V&@{(4IL4r3kU5aKk$DvyVn+EQ-{ajGCMk}M6T*9^cVc2f zYwgGINlH)@(qM>+8$~Ry83!r z2720uI%kietgQAzmaZFEx_+Q#!(gj$eczG|{fpN1UOPV23ZMWkYli@c>oyE8**Mfz zKN4yk?QN;9zNHoZ=v`ueWqr?*^<9fVmhqk?u*kN)7T08d>*mfyTY8s_cU?c;e%&@( zEK9H3(z$fHZ`rP)mWke_oBNiH4|dq0vE#D6zjb0@@$|r=y+cd)4lda{wCv!@_Wdi{ z53K5_!jZ0>t2#Cfx7)wz>R1fKRM4a*Xh2ugP~=@f1w3nc;6l|!H6ATd5*Z@I7<8R% zuuL9X_ja>DqM%Zb|D=KoPC4(~v1?}6?t=#o-EjEEn{KSm_98%8mOXoSyO43TXR~~` z`a=`um<^b;mOm_lvLO# zPov-l&?K!g1QpDBruv)Ic2HbTK4Y8ZN!u;J3Y-DK6wTb1EJmEZjBc!o`gh_4o!32Zo9d!zet_;_8fL$cV;M24NW8EIdLI zsnqI*E1*I`jlK|lnVdT|po1^Hb*~K=^C074aD78@2Cn(*UyD0rx#;bIoBm-2& zbRH7~6Jh2+=9qcH76-vJaf}^T=pi`9g6CbVe6~IwqQH^3iXamHAk4gw&!8rY5b+s^ zPNhHCpJz!v2 zNSdA>1-mGmV^b;L=GljH8xCzG1YEdbgo%@;Lzzpioo<&8`~xw|(UkLl@c z8SHCw%*DBrm0c|(z3uDzJ2wxtZys#f)L&hj2U@ocwr(F>Ix)0ttZ&KYp8ny{+4OS`V!5-Lrhj;gw5o z8)>^^P0L+tJMP}lbI(}+J(~uPZy7$ib>%H%L;J>t##i@MIHtFAse>=|gCV`4D|76q=ToSCUo6De)L zm}b?+&)k&DtRuf7j;Ur~P3DY>z-u+aF`hU;S8CBPEku5}Ba6ZsiLuQu$!2t((YE5U zNXweVWJM=TswFvZEhja(@Wos(N*02UM5>T&VYOnoSPu+I%uY-YNo)=|YDSBtB9A8v zZh#LG<;)PZA`iR>^r?+pdB@xwh>~R#3LbZ7&)I?9m{=$?><(b42Hzh zqUxbi4Pq{bv+pid-akyU`L(}fiIZg7*4uSyB8V;t^3+i($5$@R65tFoa2Ju06v4ACwiFB`UjU zz{G#OP!*;xih(G2BF2JH5*{T9lg1QzlFTY|sG2bi5L1MhX32Q>SPE|@DJ_kWN~chI zLsWy)u?8ZeW{mJfC>r^~u;3U>nHXjQbKJx+rc*K5?6{w#e)#ehGxdAdtUQa4f@3%* zxTH9P!o)WSrP8EN6D4C@i&P%Y6D5xxxF~SJM`?WmeCxJNHd^kz@3{MQ7q{JdyCa`| zd2?W%A~`g=VdHuaAUv~hmV)o}(@NWJyzxek#}f)Ibe{+Qo|V2~&rBa9msBB`Nx zZqCvL#I$#}Eooic+S%grP|5fEtE;P}yO&E|HqhJZU7=N7OE(U5uIp^s*wwP7XQ{_G zTe}vGx4mym+jWyYOLq2E*LeH;#=9478EDzmyJW}kvVE)D53cPzw6^Ppb$vIk@4soo z!28DrZW|xIbJOr$n^)XEHgwnc@?+aZj&EOc@5I^sjdG~Ysx1ZRz_2i+6M|N+zXL|j;Gg}_qz4b%8H+^t=<%efho!U2g za?k4LW=2l$9X+vU^yIz`PwpIjeAoK>rquI(KOJ*B z#l~80OzXmRN|+^C7G}}GgwN8p>QR#hpT*8gSh{|1x^l0P2s{+L|68bBg$6{6_vW^&nxzd`Vn%&a^cmEFBvf? zsih4{E+i=pCUL)_3h_9}PcoAMfQ~2Cx5cFE9H0S?v1{Vd5-9WNV@_*-z!4djr%U!@ zs_*&MIHqjIlr5P8Xo6j$5Z@km z1MJy5XL8%|UxisFxjj(}8~F`X@N%(C{SZFXncmyy6RLcYJN z%O77{=CrJ*LOWIu+^~Mt&Ffd(x_efEvcC7&SkLkCu6wuid|=zaLleUvoLrvkLsKgro?iLz)aoZ@);+U#{Hfg= zpPbo%Iel>JslA)d9o}~K(DCttdG;=I)Ao_Ui-r0UH%ovN?&R*eNI=wE}L*36WFvfU5!2nlAqd=Oqk~6%&aTBGA2efS?8uJ90S3~Wrl02+cD=A z>y9je;22N_#nQ$O$NXABiRMP!O8`yGtgtNAvQDkXvJ9hEbS!PDfj-3&TK;%RVem1| z%td7yYU2>2)HFxzPs|IW6ko*_6$O$A=@baUlR*ZYSztjh2MG#{C^$ym6kGCAmOUi| ze>6iG5ebE8irN^c#qSlAEGbRiG$wiRDKKqLV+v0>xgr-uW|v9AA~AIQpyAW8+<|^T zm05oJ$@YOhq1IPG+i>rxaJXf+Alf9M#VuDwMB=d00tfYR}lsB6+DgCb-t53h2 zJoVIbCxT-zH8QCl5>?>DADgT_5ly^7tVZs+>RBPlGd>-Ro~};+JX!lIWmT!q)xb2n zU1w*{Hl@=XueKBO^2;y3{`%{lE9I=r%dcE=IW*(MjPt*a&QvcnUAlP9_FacouHUkH z{idCJ4&Hj#(Yx+G3d)$Z2ox_kMzo+7OeS=h=vGBZ#Z$IObUm_cc%ZDM=IW{-O#O^W zM*7LsEV=MjODa-n>P=XLK`L1%O^{&~MKjAO>uuhuD?-`Bmvx9)m|C){2=V2GiFZ#l z%T*YP+C0bKj8Zc-g+-WhnuP~a1WyQ)CBkZIzZ+^aOT$YongK462u&uE*p56Dbo0V-_JUA@({T29EKo z*Kc1xV*K9a9vJ-)KM_~KA8-r>!AK=1WGteeC|^P+zJwR#=U|aFYgakFd*tZtzFg_^ zP|m(M*Eu%sGx*g3UVp@~r@Q(}p1eLu;x!^a&8x4{jjVEp#&2l8hX?Y^f^G7P+s^DbOW7=#=$S^sKUzAdnXyrX|LYpfo8n4>}>D4p{{Mq zd+y)2{p_6wFWkEOmAm(S?B0W~AK7>5)}3$Mwf~Jf_k7}>gKylu=hY*7F5EVK^1#^h zhsK_sUh&lA;EAc;vonLw?-@R~cg2~Rp$q$0J->V9ncXYT?Ok(bX4RRQk&6e%FB}*< zzklPoeH+g0S$BT-+H*5>hR*Ehdv0szx#^+jr&pfex%%SHl`rmC{?gu+kB_%Lw5j9k zr|88lJlXluME5H@2TyP6dTO-&+~mq9$NHX}Sn>Ftji-;_ zysodcuVa}PhXPP^(a%ZruSl{RDWf0+VnnIw(z?^y;TUJJZN>lxq3T%7&F{C=9ciw5fIRZSfeG-6xW4r)gpXnZ--Z8OlyVKp(XZn!p%q26*GyrJ$ zC-a%f0%#nKG66J3DkiAK6hin!O{zkQGEtRd)@|8Rz59Kr{+_QbnV@+s3~4Qs8v`2) zoaKX0R2Y*h3{w_kmZ}yat1@z7)@+ey!HQb-#du=MN^e>)JT-=b4Pje^F-nzptoKVQ zCpY&u4Jx-+Q&K5JM-*}Y@$^D`qVsSG+#oeRIIfghK?w_$!HD1$9yH{5FD63#ywo|Z z+5e>$98=nZAxt6K6AE65j!@f#+M|TrP9&o6w8>)*uxy6X7?lo;S@yP3a7@m}*pdl| z$;ap%^|d8~cQ_`HrHNxso_Xrj*{6lBl3MM`)PL2eyqjGet*ucAoRX{BPdRn+32!@{ zIc-1Y3Han>wZj6?7#cU?h>UZ%_KFBI>Sp=>;S=+TGm;ymin zn8%LKJqyO1Ip=)uS)o4+nWtJG|HQ}q{mZX@?Mtp-{=(qme4SFhQ*|CX_dnb9p1V_PO~zuST52Yd}Lz{1HG zIL7p?r~2$sTuCI&`CU*5COm!XB)%uh#z=5HsJXf%p^^ooWK>p8Sz1je*W@W6YblO1 zD<_MJiO>{!-ibOg3S4<6L35=jtm^xDx zMA8fi=tVW44%7rVxr>F{5}CM%+(Qk8JG61jn%Tj6SL$Oif$`f50wq5|NV>2A`xj6+9=0 z=V?44^08M(cVU-XZoT1-yWa0}Bikqa?A{39C_!HD-#Qrzop3Fby{qDynx3Qs&;T(= zllUra0kiDK@Id?}Oe2Y(vx^YV3b$krW)8s2|G(NpXseFDF7?c%zA6M$3*(i&=Ho*z z>xVjSo!s#7{_Rih-gy4d<_m|%FC1EbVgLGbdq-cpaqA0v)}7nE=EA{NI zK6-fLK=s`k?_GEMv)TV8Naq+(BWs%^h;SC})UR+utDXSb%(Ks7P)sCyYzOuqJbdVe z8*jMD)Z$LSg^IcTR+sq($JmUqC1VmoC%~(xiXJ$6PtD;NPzC`UkW*%((Z`sd&^8o% z@ZdpH7n)hOZe7rowgs|aLIuHuF?r_U7*o#9P{A>NyT1pHsm*N_1m6U{6x*JqY8l4F zWj)sRwc1j}P$)W)3+Le&c`b8BAO<1UELMmd!-TLWLS_WR?BsV8FUSz#OEi)S!pt4x zi-c$8`wMaZOimD`yiWk4`B( z(Wq%m+J=d~n{qFr)XWe##)#W*WAyZVdbRihXakOMGA202evFrl0GFKhU5I0{^&<4- zC^%*o%81q{d@G=ncb8z26aKu>bGCeRzV-kh{-~rK6wipB^qB6<>1R)$0%(F}cozW0 zz&R1DRn@uRx$o_secrj^r%s+bb^hYH3opNL;idBzUwi4bH(ve7Td#lgt=B*H&YN$& z^X4Z%|EaHj^DAHd_Se4hjW2)WJ74=-KmNgwfAa@F`tkSw@Q;4yAN}J$`}2SFCx80i z{qdjt*&qG(@BKQ-AN<{){Pg$!_HX?3hrj*%KmOT&^E-du9-P} z`}DpW$0m2K9vwS;%Wd}@zZZ@{I_^Up(1)r=1Dr~8x|3vPW2n_mrwZuESeUF95-W$} zvD)YTN+7Rlsws;qMJcmXfiKZ4tx`3e5J`MwMp~HV#9vA(D2F_hg&LjWTuYX$Lz+=j z2qFwcm~ygKvr4U4GYn;ZSnI8zyXAT7y>vW#2Ii8KtqJ0Tnil%;6^Bwt0Na8KEvaH{Rj4W;mFRdPrmvi zL5_7+fA7%uM27qY=H=cq;`2;wjn^mI?63Lwy?*@OV;EpXlK>ZGsz~{qsEV|ZljFnq zLfP}fD{hsGbyh}LBa?V!Y#-?cL98?|EVO(Anvp)6)ZwZ|Qn+OZTa%zE^h- zUYhKDVN1)aJNj*$yfoE!ak?Km`RM-9(_4DaY#VxMX7t?jYL|VNm-nrCY4`A@U7fGa zbiTQ_@8Y&L%3ru=$A#^kFHLs7JlXof_SW;e`t9y~>fYU7`rzSL_YJ+eqvMUq);A|x zKRVHRZvFKi-@oSXUVQY+NB2FqssG7MeUDA9K7IEAZ*lv`UZ*Ez|Alajo(UW(AZ8XF zIrY?CoxBOa1vP*V8z;6{z)hpGXU`so75qLn!QdG0qj~#`cj0NA2zJgFjFt+s!Y*63 zj>9n^ti72E$ZXxJD4TGG7$!EO%mmZVgCQF#W-kJL@tGcyD3~W2gD{9BLen^4sO-n2 zRsTsGV+9prZi{7(Rgdj8b+Zg(=)xDF>7DgRZq1g}inpSRwJhc_wlP*B7E%%>HYyf| z!C`r7pfVd&D5j=hmy!g*gh-@c5t=kNJPJ@~Vg)>ufTRY#G{Yv;XhIq1Nl_%=MWUD@ zsbS1)(9B3A8sH+ACnFw|B#gFZ04`dE@EYdsFz!x9Bg<|WZd1y=?|k|DKltWPe(%?R_Q$^~{GH$bjX(YKzxPl6*+2aA|M4IEvw!iA z{_X$zFaGtv{b#~|{;&SxFaGJD{nLL={`ddr@Bi*U__II!ji3JDN5B5v@Bi9YzxM6V z|MFMfdFQhq`NG%U`TUnYR^gbLL+{@-J+pRf>(tC%Yt$=CT!oqHtA22dnVLzQd5lL= zMMD7}7K0U%9w$jO>m)0O<3UO;E2=OQvX)9NC8XXIrJ__iuj({_kTS9YvyieBg>j#R zaj{uZ^HyESq6GIPSMkS^A}mlQ$`qng7AmGV__BtJB&kte7*eya%@s^q7)e%p6HLtG zqmWvJncvF6NFq^J8iS7^Fgr0OB_@^9PnJ@6icMIAg()S^yOFe!_~k_>5z|wXkA3JAHBmj#<;W_{m%M-#0Px*wo60H+MZfJ#cpKif1Q#;F$9>D^5-H zotf%CJJt8}mi9|C{TFxioSp7{dTYmX+q%wAcD=EG`K5`@kIfAH^x50Lde79Q>HgE3 z+Rkk1_>+%4`=xvLou6L*dzT*ni!Z$P_djv=&p!RapML7>XOB+4vb+0@-Q6FVYJYyi zqL+3I{D)ur^qYs*T-e(B>O|`cTbG=l?0$6Pl20Dn{ja|N_LuLUetmb>+q=6yHn{|v zIlJMyPaInJ@4xq{?>%zIGvj?vZW(xLX6@N~4vY;haa6ghv(*XQS-|n1_n$s51>h5{ zuw!R?vkC%9W{CL%ZkkTsFM~5+8i2;WOWvu5P;IEdF}@!|29ngGxY9Y|Nnbj(KBC6L8DL4h)vwVAYL5sWUok~4Yc?Z;$G zX5lZ!Vr(&HsjygGt1PR}lElPjViFZ*IY$ypm?cb(VG?U|csVFGC#I=14Ok`QJO~qP=;d+H1lGx*cSa8Bg|X_bDrAx z44vOsK#a?CCC|G-86d_vUth!XT&am;0GDbfroIY@DVQcWX7)AgdOt>=YfoH*>M$C> z$Jm28b^hGR=g*!No<8l*I=ub%+m5Qd_3=0J=*MHAZ+`1*U;X+QJ@>J#^6l?`<+pz4 zM?d?!KmGNe{NN`){k7l!gWveWpZx^$qrdf?AN=r}-~0YozwpIRed6ucKKZGSe(KY2 zy!zVtlV_iJ=G4O<`tY#_AG!Okdv3n%$ic^+{J_n(@7;TF>cEZD+om>5?A$Q9YvY#5 zwd317s_z|I-9EUg<(gfGZ*^_ixo3R)j!oOAY^FLQV^7AHeF40O{DFnqyD#)Q@iE*? zC=f)C&k3sk2}6N0SwD0NHCGhPI4Y?aHL4;)MP;RBEzPUCti!A^&JtN&!m`YYmyM$h z94RXhla;9`e3T8F65PH@g;k+*I4Mgu%eAc1IDXM&FR6(ZwS|o3Ew4F>QF1b-w1OV4 z$j~X4q7+i*dZu8}5iPcZu@FtAS1g(EY7Iz%3-2PgnOi6pFmoUS6sxBX)751_n@ky5 z<6cdmnlgDZD}?3@0uh2^00_1lj`90AIEMRS>-ix_g|}!T7(5~Oz#jzYh;kSZ3<*cV z*>Ej(O5hLmLP*@q$ePuwRxkH4Uw`ay!`NDgjd;HWN$43vya&hm%m{K07+Jjj7_0JZn%jiH#P%Hk&ZD%4|>^Fs9q~K}Q$7)5^*F z92`+C>2B}ARI#>JZ(NVGU;E*kcHX;XrN=ZMIWqIi%!&s#ww%9V{l|_>pWicbqS}TT zesRz6Gg~`e+S&i&ROk7fJ!hu6pP%kOKh^Wb{^9f6THe?<_%FYB{%@an{|nQ-C%3de zy>aPZ{>Cr;`1#}KW>)^2U;Xs|^T)sX7hn0vKmGPw|MwsN%AbDv^vk>Zs$CX^tY3U- z=ZgRLAO6-SZ{PgV0LZ^Ti$gk8E7}#*tnB*U!HFnIoHD+`jmYoh`3!yY7{V zWzVgD-)s9v{_@9P`p#oV9v$s`V(Z`uhjs2dym4sp@_|;bUo}BSvmgGde1MBw6@;04 ziU$Ph;;PeX5Ge{o=B+Ujv%*v{OhyO(FibXAj5}OwKxbxVrY5Hc`Umkajm;R4_qN+_ zx%=pycON}s+h%8dTFY!KPzHj*n`6PXngPF>0QP=(EW9~sl7K8VjHz&ps0N_OF&ZQL zLL6fWSO^HRe{URP5h2st^2*vQ=3O*=VMMK56nWFeRtB*)iLqKSTr9&pTNGnbLYC)h z7^Q$1%tD={2ATxEgcphyzA*L9&g?g7fP)&wRIj>Fkks6a35Y4MBRC@=@L?aNBsF(d z2Z>pP_rC z`lCosJPOBDf4K1xpRv8i$9(U;r~1Xr?F#24m ze@Wqi=ujyI-!r$~zx<>&;6qTsZOEiASG!`~#0XeEj&a zTW`5}@7_Jzw{0C=H#)R>Rc}|%;w7!WaQ)K1wz%bQT)X%heBV&}U;D*tu3!4sNtU$! z;?lP2TD0u1w{%=9T-N?R*EKUY+y=)?>^ZP$V&~?G>D~U=+`&U|%&~ipdyC7TvkaNU zg$b``<7N^T6oOeubgHFOFP<<7Iiv_JD!GJ_V^pV#6jjz6p%pc+YSFZF9j7DYtV!f;#y#iz#Y3U{(zCw4}16T za(T1bZ*GsAXjWNlFn#Eu2R?9rE;t6PIa(bIt@etv&CmBd?XF==g=4r(?vtnFv@`?7 zn@WOXgovb2<$G)Dorhy=SJaZ8j$TZKYdWgGShTM5`bQ5=!ZBVf`rWtBy>@i>J)=v$ zd+x#Cd-LS$w@y5^nWtd1|uv{B-|o`-U%0cYpNY zivRP+pZx9fN1xl$dSYwa(_7m9mmj|UE2oaUaA?iH{?Vs?_RfiCb`3wZWANLjj{W6N zzVzwaH(uPn?5&->XV)+O*x`-;?|=L2@7%HV%$Bw{XZl{AXn%ft*P|O--#oVG|MkssqsaxAKvi4{pgF|dHmQztJ*)jb?CW+aWVASM_!jw#mIffwGX_B;`iFk8mQHu>vI&THF`aX9Ao zJ8turZeD%u(nnr@&FC9+043fCe6bmmT^Sj-)vs!s66PL+q%P00<#uz+0mNO(H2c zCWs_a@6jMTD?kZ(G6thWNDUK;PAQEr)urkH7j4VljF4PW?3-UcrVaaMu=IIsuf9bu zzx?uRA9=MtQ9BD_JXgvesm^{(!7;wi3&)gwmw=elXHVo34T7mZ6;pl7uHYD5l*VX} zTX^T4cfS7huYc=1-}%n>zW2*t`SO>)@%3+g|9fBg+Sfk!OTYBVPrait&gYu^{#Ld> zwSD)o+m79T$Cjy$TPHV+jeFf;V4%;pua@{eXMb;NZ?{(zu5W9(wzGYa&qU!{m;U0? z#ebu1+51FSkMs|(>RGY6fBCAu!R6f>#z#g*hetQ86s}%7v~klKl64zbty#Cc`f}6S z73(*y!CbTFraN{XdjHhELtCeJZ{IPqW7o{|&RstJboY^?&iwjIk(uko%@oiOm&3-3GF1eBvwX9wxTc2=)*;Z-^fQT}lye##?Wc^D@#uANWo*_uIRFR5O zOUam$B^Bi;h%yZ!Mj;TVDU?JQd8q<}N>Sm3rTtAt8`LY*T_FQx^oy+|)Env27{_8F zGr=-d5}F1GFElGMLo#7VFu^elHw%t#y6L9obEWsdF&sm7WiZqr7@IDh@7Uf~2=Y^# z1(6D8`1xzkpO=DNTn7&B_0qN1YdtuyAH!YQi~(YN!@yec9XwHJ#%u>-w95W)O6Je_ zAq67Nl7r+LYq(MYm*P$1P=j(7x@4(6b|~6?G{(u14*M})RT3q%A5(*vE}y|&+0(kA zd+~=4P58vzv-`LH`L{mxn{S@Jbm#Ox{>~@=$#>p<=bk;!ZtFX}z3bBcm1ib^Ze#;OU9prziTJpB}t4Gjw)y>$&ZnfBD0=fB(h%pBZ2J?3UJtN3Z>#fAH3KPu%|e z{uTe>55Dq~Hy*ov_?p{>t~t4H?fs8G`|dk;Y-EXD^V>Q;Jl67w`}h8bzw^yk_6=Ov`o7nv7JX#$`j;n`oF2RW)dQn&%&$Cs zKOFPK)}g2NtUG&b|HgquE8v*UW$(QolYVQ43p?$Kl4Oyjs}ZnL-VwtigQB-72=P%9 z<_{wnN;AhpB{;_PfJ?ld=2fP5KKb$QegE6P_M;zu{1b2Sou<0IJ;(!OF{6MLlg&&p zQG>J2qQ@t9ekpalz=dj zl#f)JHl#h87a_G*UwzeZm?tKQ!NRAv)2mFVVuNEq8CTxBhGX&x8BoS^CA%{AV}fJg z6<=V1U4mD9IL`T%cV9Y7H$jNin@5HQj?voBfBy5|`qsC;^rbI-27UI^pZ?ruKJw9z zKK%HH^RBg@a2{*=)aS05oin?p4j-}!vU_av+Vx|rH*8uxw7R!%d8a*WXv23OeQn&A z6#Dx+2L~BdpMvc1r&dUoFYjA9Y=gXa&8new>sD2N>~@24GI@|gfFG(m1buM=K;S_nHq-Fu97KLYJ3bSU*I*)SN zP(nza83XWL$ z3_b7>$KdyCZU1KjE+I+cc$&WRVUak?0*iPL#Zv=GTpG0D*D#0SH}uY(J1r-FEQ#i! z!}}fMwWxfY-cbn;l6+01-iEo?+1~1n+`I1ZsWeAH{T%l*-AhS+uk&Hr6R%l9Rm4;B zj@)YerBu{(qU52tQmDnn$F_8~yD)NALT~o8RcAW}`?^;5w{7fM0>|98y7SbH)4%oh z3xD#BkAM03`~US%zxqFX^R2h;-f?E<@QKZBFYQ}(Vteni6TN4q`=6NTdtzq!W83isvr`I+DR=)=cG ze&NocYaZFw^Dn>u_V2!M?A-WuZ%nqGT>Uqm7+w4y|LFT)d-Tv_tN+?tySm@n(Rp#A zz&+S<8?|$uzKREH=2UmA|cys>~ zyH=k*x_9gHWh29$?6kheIp1KB3K%vh9k?*mhY=Pg{hVGc*hSCd357IOK`s5Cut?}g zGK;F2HarN&m_J??{na0Q?{|Lpw}1Z+e(#&#{O0$+|9z8RQGQ!dm|}now26_?(W?xm9@Z@kW9JU|$FkOVym8qk3x z=zTZY&F*PSwl_1=-80j3v!j^Zz159wSGN(jTJ7%bN*7X`LW;OmNDz^s#jH+zfb)#E9+gpcEo6DbIS@}z`v9)#>4$le4ORgr4dVBUi=b^ zVl!JWHzy;%Fq=t)X_*O0sWDjvskxraqT&L_dz|m57D6X5iaaT$JRBAmI7=@T7Znzi z6c^F8(g{1S{*}>2tQC`fSW&`qe}MM{v4)m-ODTX`)Y8_~(73v`0gh>}tZnpF)|6M) z);G3vbgu2~8yX%O;hRyx0jAM$Ce0v|!n_$N7*03N$|xITnuHv(ID_T^us}ERlmLPZ z2Q9=gBvW43Pp~4HkW0wrB(y1NY?MbJoyKNSfNPI)w=NnFjzm>Lh*SHNOvvV8DTPmzp#o#dJKOEgt)?0wlRhQlVP4bKt?iUEr}Q9*F`qv067KQLNf+Fz2fb4A6?T_fM#J#lT{`oI6~-fv!;o^HwC6^P$mw(MYS>UMwp zHhQe*!WuAr>CgQ=<4Pxn#sW+J z(@!t_>guMkf)|IgpWjxV@^=rfe1BqWf6?N(s`%-`SK*ld`rZ9soZ7fO??pzMcq!>b zRm}F{muI{E|L3pXzOp*+MENV1s+P_LUYRLhI#u-Qp@y7)`uz2eb`Ou|EZbTVzr8jK zdyF^r)m*;Zz^5XeAtM-qU(D%ppD|=ksZ_qstvh$#8F~yy1SNtPLhvHYk*J-jqz$!+ zvdjU*$FdMGYd!OE1MVNb56b)bj5DHOP**4b1WZaysi~{4rGsV~4fqT10>|8|RaI4l zVr%XbZaiQ`9K$cd9;5qKAz9p(AQ7<6vnb|6*<-jNaSUJ579e{X1x-WGjZTXRPAQYD z21Wa_T`O%9S?LJs+|(q=Qtzik8n5la=Jx>f1|%w-(B0eEj?tZ{p2UW9FY1dBC`Jtk zbV`6rkYz&u#3i7K1mO!LKuH|w5DZbvF{BWMW4IzB8=~-vb)W-)f`c|lgeL?dr)Ou+ zoIOj31qRZ=n<+3eGvXDH1vfi8OGtSVkwFk)jmi*`rJC6kff_LWa42|j42Ohc(l5)@ za3myB31=Sg<;FngqHyUdO=r6uUfIl>N_>uh1yYz6qj|od3{2yEl^Pvsrus5D2G5#! z`bZ=Yb7-2`EiBQ?u$-9_gTPDC4#$`wEu2n{80+%o%MTuYh*|O6`LhFqz1Tlk+mqXy zkjaAdX}qn;ltKD8%qOg^MY_-gWMLghJiNlY5qNAWOo68t<<7?oP!x(+luH3jjJU_j z_wI!AlP69M?bT9ug!FBGWK}DIm`9usqXVejvxF1}edEX=z=kK&u)RRXdby z+nbsktqzB*sA*)5*~3zZa*0xaP>q&d;8YbMvMP6ygMr`VNIQk;3f49{Kzu(SCIp_F#07M0F-P zX}W4$AURH&&NEp!ok|39b(83x(fvcm8scH|pQyVdMi$2aG0Z{1@n9;g@Dz?gRnRq{ z4_G^n2WUR&$HLw;)KXs&_RmD{1_;P86J@}E@jm!pTU$%b%&f#gOAHmEZTl)$^URMEPXuz~>6c`UHix)3OM_PzMze)?vSF}GUg~`0pu?f*JeDxWR z!z_S@V=&AxV>vm_a7gcufMwa-PK)tm#0sa$L=kU z*&9gMQW~?ZEN)Lt+Rn+Um(rraAo?q+x=kMRT)>&}0cq@B%X~eFY^nd*P^@meK zL+OhreF-~iv#`gMq%FxzjAH$m_>e_}UkW$Ocbr(ATe6(#dTV_y8p>2dO{|a-tbQ1|f;0h(AuAK7H!U8BhfQd;xZ#5JF5W6p$0d zU~wT4*+!KD#E=fYs9FO_M~}iW@*D=oLr6M>FxpUz1EyxqJRHM7B(DtPb>@K>JfC<3 zUoZ@B7#$MFa66ICX9}1l!$+#Y7mP8ydd)l7n&*op28c2K5T5`rBT5j=;pqcdS=hDC z3?V0q12}*F{AZti_U?P{aO(mq+|qoBmT%KO_rfC9GzUAlpWzj(DGaYOWsoO8LY4`2 zqJ~$Xc08~`VbKO5ou?QDvcUr}Sh#Ucx9adpi9s2nDqzA8+>j2(Sd=jkQ)1r!!|_pi z{31U6(YRuDV{->488{|TyP_;m!+hVy=Ju}cp1$B0myAUQFTKLO&RNDu54jtI^cJDp z(L882QbnSELg^|J?MM^NOl8!@sGkj0QnlF~DM|s_7!H9Ha@7K9a@KMA-Ojc^bS>%9 z(}aq$6*W+soN7}FmD^vW!yujVRKm8ZmZod#SIw&SDP`Q{ku7{kPzzVT5LVLeG%Q_F z+lf$vJt~`MI|#Z7`VM*s1lxVsZpB@*wk3;$ai=45Byz~w7r$2*#hx^sG0rOKoHRnE zxI<2_?h~#)j_aoqn!7wUA%jDU@G`uoQpB_enFvhUJT~kvNQ(+hgKy4rcF`x`x3@@jkoKQ>HV0hcM zvZ|cvX6c#9(rOS4PwH5GjGl9bjojK5jp&a4e)1DICLXGZih^TO6P$6S#HH9{h68zh z#TnOk41Im;$c+O%zqoVglbNx}^4MKv%MJu$4%Z}^cddQVhb!Xu1Y!==ChrTx?XF1N z1mydvDRPMA zQDDJEaP#!jCw{A5zH*+`ASyPN(1;prfeLBZ5+`#<_$8b+# zkKwkLF@`1p#5{##)Ns_kge){b^>Q>x>(qJDig7e;^>UJlhBbdhY4|wXYe^87xce5; z=|gO~dLCg1AH1RUscNP;p@h;gTbGy~I+?j)EIB{`L3L%@YB8?_Z8ScqXq5DX}zL=FZA;{Y)j zWAH@z)fA&YWb}|B>1|uLvjB?DJg~ye!_W@~KOUBbhWmNrnn5MJW1HDxz81-1>ElD1 zB15S4V+1jnWE^%mFn#3Uk)wySx<6;;;DJN(9480%+H0@P&CSv2aSzjju_8If662BBkIgh*;5XW(!vz0u#Y+hMq%-lREidQhJ1f4@a zp-6CZ>aZyYL}>yzGfSqpcu_~ky5_cyrk2izrd1Vn&Hm~}d_{FrbzM_)+iGUXm{~2f z06+xqJQmx#Uw1q$K?+IgKTJ7sJ*1Y@erzb9p~3|@hGNu4s6DFHQI#r3z*)Vh10bq4 zsiUG<+6HL_cRN(WvzlHl*8Udz8K!Oa`hs16JCSxy zBNs^^NG6d(rC6x$A6k!UU~}z)O5B}@x(x6IL46Im6t<4?IPDifM@8;}KZHbk!Vx$* zTn_i0fb70roJmp?+G0d4%7|ku#Bh^Hw!*-Gd0&YKP#{MA_{z|G*Vx`I$Dk+N9D~dg zEzJPiKBGc>j~d_rHF)fxfoaMZ4U9&Ds-Rs#MLa|6{c3iH&S+_AX>DzVV`zkIqQ?#_ zt9&339*T`evoU7;3i^y?cIgG68T9M2Wz1tS?&-Sr2jw~(V~sIv5@wG{ON^5}W~A0T z;LC<%-rT?G<4b$rKfCp_^OK*R7(chBWM4%*ZzmnAPdQwjFkKaYx*>JCD)v}y(t*lY zUdi53k+iEKbz|Yu-@SJD+u6-q0|~nuvbxe<`cGfK@#VRlgQZdb5zSlHoAO>bxw`QG`*)w5YtNr9dHHO0)Um2aIObG)!GHbv zy*CCc_7*&Qp?cZ*%7|nBC5I|wHkL&F!zZ^sJutE^{+XTSNs~314#z~Y4qjqH(B{O? z1XfV?b`%MLDCzFA>XyS!roe>@@gxVvxU($BAh^>XlcOTJ%2;CXd=Ubad3A}o^!UZE zy!^roFED|C8;sdAeDnaC!84-7G#c=iRW~r$@GI!Y0T+Iqej2C^(CF96JY#QQZf49j z;uvnxFpj|_3B;&T5W2^eXglgi^;oD*n6^gKQ$J>VNCb6R>e&e8)cLqOE4S=)6^|y; zsSlyYpnHK!2;F@PG93=-I0+V9ltL8#kQ2%vqitnMu?%Aru#<@H7l;TKC`LM)s9HFN zsNITOR5ic>cHofh=CBA(gn?NFj*)Y74C#;xAwx)T4E3lgHl#L1*~+OYSR2PC$KmM+ z-5g_%=g1Lr9I%vwQyeWZE)AUw<~ksT1yHyyoNzb>0%lx^_X${TkwI0*U1vvl1Eqi)902Gjt=4SMu; zUOP1(W5P?>+mOOILnM!T*obQJ;uz^CH8wRfE~MGYAtzfKiBgcHs1d5w>0sQd)XKJH zBG4u+4ba%EZkD#D0Igd4qH@(h3bJ;GAgA4_Le;4nsN5Yz*4}NREoKkH3S{Y!Y%ie3 zuRg-PA+iz)k;B~lK7|78g>=;q->83~6G0ZlAdqXTm7opT7D1a6+5?uL-^kD8%;>bZ zFOXz~6yRiXR*7;;*lVhDOQ`#Vi|*WL!FQCn_1sQ(3lKv$O|NY^29y!UU~7R?=yiqwDUw>B{a|FOPC>HK058Jb5H1uIPkXNV{=8rlCR7l5I{aHqdB>(&3^i@Tqmo*eNf z{_fq`Kf8NqxZtHNzUZUvMSuOy?62pxY{`H2R81ToA~@2Rv8_Dz|NZj^cQ(}S^}Kkp za@pa^$gRaM&$Q?N^Do}GH&nSZchQB~n7PVjGl7VswF#R_mj3<6SH3#Dp(p8??Pc-X zs?wctrKMR((c&0%yxfyG<|+6RI!WfeBq2x`uRO*juE>)(MrIp@4#XIg;aYRWxebsB zBbW!d%zU?;!%j}Y+Gjqd?M$PI$2`MxDz+KaRZUF|q{2PM9ZN}m9Z{HuP)vj1zIC~o zxvRP9bbr=4?<>h3gE58yR`3N!yP$R8)TyfZEXXl5IvS%z8QQXK&bDB7NXO-0%UTh*t=a<-iw61x>F+8&z%M7_umUjMFX*yf|Z3V2T`3(Gn>b zV}KYug87V-17Yliev%G~dqdigsOgOzOCB7)`vA-4^8BjgRK1Z^sgWd%TSj4qEr1Zu&P zD0_@dGK@Dl15do&X}&l{M+$%#LV;13DC5|2gh4zCVnOFOnk>h};tq|m#cNG8k3$SV z#mIk2G2UUO!bR}Jnzg;nD?6F(Tfd^Cv8B7Ib!}bK>WaFix~7(v_Enwh*3v8}2FFB_P?n8s;!GlE*LMHV%0Z9-_3vDL@y8d(LjJGFM(=Gl>C<*FB;{j23K z7}_%GCc-)kZDPyVeqnx{HpSMXgP{hS!shfcVi!U;FxfJc*M|HM?N>D*<4EME*^^^0 zkWP`V9T!e#(k3G4B-`6VH;K7DHU!6#fEfB*IXA&bri}qH>aT$qCN|Q8%N|3A4&8$( z7-QfVOE3sl86cxGm|*~jP!bu4p&`*=Fix^L>g~RvWfA@_y z?{RG43;l~U4LXuX7O5^C!S%&ybQmg)bo3UuVSvVQKSbABrTY}Yd0lA%jxqCmIUYXj z92cDtzqBM}+4yqbhROn_$h>)I%a2cN{ncBuSGRZn;?nNdhU>TIzcka3JkykUusUVR z7rUn_Wv4HWnK1_|Vy9~o57wmYDo@-~k@nl0#~vQrbaZ{qzk6_Xvbp%r-@Ww3g?;Ur zFaO#7Gv8g=-IMeDXi3Cmb?Se3_w3J4PmJe0v$y2cncC#(71`^up8YSsc;lPX;|Kha zM*_wd@w)gO|k< z4{-IxuLg1CqRf)SU=8;J0@TYb!5nk$G;SpBK<+(mSB?;Nkul~e9HSf9at!RwC?`z- zV~m?)Xd^hwF%tB6puUTisK%(CleTP|xf;0ba1asY=xlF)n92#^Q-Ax8}qAS4R4SekLR2o5tj0AK(GXJw#)O(+khARAh7 z9A$(N2ude}Ip7Z=2)TfZj4p&hig8jXppr_2T0}OaBTyKpM2BPy%HV>#<1ieGA}U8+ zP!Diq*oSh?f$^Vdwjdw`z*7@FA$=oPhqI^e7Qr!0vBDn1XHzzCEf9UtNwNW}~!;lUTj5@RO$ienVguL@-dMINFVJFevO8KaGQU^7GnnK->M zoiI*Ocdk<+_`0?8CX{&}YSHM#SnuEv%m2bL%bU9z+j^Q-u5W1Vs&8Ih*W9+erM0bN zb$4%%hL$Ld$EXFoAZ{EF+F*bfv^^~Zy=8ThX*LeNKrqfk;c=l1mqi@YJH&c>kDOE& z8*$mJqc$}>LJ2fE=|ZBm5u#9Wf`%uB+zM)n2r8_`NysLo(6HGZKLMx8ZMxa_KqqbsY2y>OP3t0t*VZD&;DwN(3~v z9(ypVlal%&?!!N zQ=E{)=vpfIp`}f|S+48$j zZ+~(5Ky&Jg-`_d@-L->lNsGF(Um7Zk{15M)|MkTkBRS8q%*>uZ?6!);uIv}SKEM5M z9?qR;&fZb<%D(EviJ~R@mgoHKhnL>p)UrGO1s0W=DOo&Sx_G)GYN{gUfBo|M*V97- zsn2fr#cd3v9O!F=V=|JX;21-Mj^iA1&JhX!04TH^GY>|dn6MznD3Q=?=HeJ+U354m z!g1Uf82m_Qo`G%#3IICX151`HA(v7R3}no0soRNPXCVd|+l;++5hz9o`f%&gvty58 zZad2j2x7!B#tzfpPpc8T&}6JkE5q47({^08vvLb+@}x*0boV?CmIMR!9yUdcVl6As z1{8t{rWm1e#U*5+H7&}BSI82_$cQ4KAqyucvBnruRG4%nf+Ln=00m^y!5XC#N+8Q& z2J($lA}N+UNJOLKG_SFZ#jlDj+TN#IQzySvDNrE9t);82DlN&^bHU7^ZrxFQQT>0k8upO zq4})JM3x4X$|T*k#-|7XhnRz=$PJ+yYzm1qR}!gQ$1jbm25)z5m9%@;YWa58w%Myf zce)TkB(Y#<(LuTDK6GsAM35y=Qk{ZOMjP5XwIf@b-Gl<}L}UZ_A!7^`D%aMd-RUqC zss?2JI!+*GOlL!9%$_1nBbU;-_=X5^6wtXvM$oN60c1i7o4dtv^uN}HZjIo7^2x#& z1Hs@h#?W^&KZdRxlMMEl`5eOoE?vKM(gY|E)CT&4@8kH&{H&P7>eb5|8d=tiM9eTu zXy9!o3@}(?PM$hGKCyvT2id?V%zHq8p%e+NLPd3v#pAdX8&MGqA*$;SP`XdS9dQf= zj8VeHF|x-nu9T6S0LOR|mN3tEthRU{kaK>^y4wdv?;akzwtd~*9qTTw^|3zhzRLKm z#Y?8^QVvul?yN}JRF<&Cmo({5n5s;e^u=r{jvCF6`t;<^fB5!;KY9D&&+pHE|JLk( z{O+f%Dg=5ZCM9-AH%KVrEzNNeT5&zRC7rvSv7|8h1 zj>@F*iWJ_vE=`X}ON>lRG$S%n?VN2K+8vEalSG2HpI0@?zOrr}@=Z)ZGOZ;8f3t07eHN&{4nYWhUSshe^)d@G0b2}ITNsOwN@ z2?l`_nOp3D5wroRkVTz@q+4)-SKtgqZ74J$-O>rgNW_r>lt4DhC7sGu2`QFWgbOmg zkci*_jIqZc2x4Fh;R~VC*-9IdMHvx^UZRF(aOikNF}FY}iXyu?Mg&7hI*0?5P!*0k z1t=ywew+-v1dK7V$538JMaY_SoNBatZEfwqzyKGHYotLsbCP%MK>zYFFLZF|3)MTJ z8Qx@mh9W2W~$;uxOIjzeX~Pwd&f7sCwK2y~!(#3qf= z1?CWNAP8va1|bp>Ws;E~V+_>7>>0dhMnFSUm~lA9Xeykuu8cGjAx;BH3V|4TcBjcP3vvuvO^(eG2vxUawLq&r zg&GzYo+OAx2q}OLrtwmPoO=`Ph;&Ng5R|fDsLgFj>ZB@#VG!fqg${rMVJ<8^j2>*a zLOLZ0)u9mLY_0^mt=$DFWGNj%TiH-4?gGd*s;#I>N2o02I(?uCI0;}1juWNRf^4rH zvbhx;z}1;lu1(kF7Ru1ustXp%5S3F$tWX?dX@-YU95mC`)&|F5tEU~R#|L6?(gY$H zqT~`%fTn>xrlz_Us~|JocqNZ0(`z`efx&*>sm9uiNv5LG&)bGPQor=_i(2tXx>Ksi zYAm;cL?%5<#s2Up${6>g@=xLzK1{+87RnHNOjcrKQF6p^eaT=TZ@j+v#_r)arZ-*M z)_woLhI^B18CT-HBtCY%-5Ys&dHRvs#NC0!t-ko}zJ#eNR+Nd^Q1{^tFU&Q5mbz54BygMV^oW}+f(qC9zaUG+bGar>QJYX-8O zJJOUj+g*0Fvt%@oFx6V{fB(hj-<;XPJKM|@9`-~`)#v@~gKHn}T(cwVxs&D5GYmQT zBledqfn)ymy;DCsKC(XLnXToC6P4*ZyKBobm+^h2goG$`KThXFA!kM>AHk+rS%v4H zJ@@spX!5Tp%)di8a&ZjYW`45+H;kwr3}XVw zMlxB*=g*%9Wst=&q`)qeCq+&vva+y89Hc@G5=1%VQkas07($Mm0(=C3vxjPjW4L_u zjht|uLukfX_-;E>teEyIeA&Bi$_RTV8B5}!i@_!)$MEVkp9t8zZ8T_)Illi0{@6id zm^pTsk5NNX2Bwb9m?<)c4|DRHo15uBK?G*5Kpvn*&~vvv?leLa3WN9p!MHuIg7O9^ zMja|tNe4cHvaJtlv6LdC3lM{2#9vO)V3xC(FLgTJtf$9!3Gj3K8hRadhR_W0>F~juEw>1L*qQnt%sf)BuUhk1-Fm#U(5=b?5eL zw{G6vyJug=YO^9Rmy&fYd8eAUOBmF6dGQOZ3j)XRNR6SzgpQM@bZbYY+m!i=YQA#) z15%#EF|xK*QfWa^8f78fp5?4x;tFYWZrGw zWm6@~W|<{Z!%{KvJIbPX0eiY4j#rir)g_PRzcQX5_1V$M|L1qVx_@wEb;2{d*OdO3 zKYRGq>+`(UzbN8ZcRrOT$vA`X>B?DI!Xl}CPmZqtW* z)(+>tGFlS1A&|DCyP-5AGBt5&Ts+>eO4y0gxg{NCkM1WF&?rUabs^jvlEO6-yO`0y ze^nQD02~;H>i$Jx9Ak0ZatumN90SMG1T4qUC@jaQHPM0)XmPYP^;BxkYQnZRplQ4N z0YynsleYvTc5#CXx|Kw9tx>Wrf)RfRI4r@4P9P6CqBaFV_##pX6)^@F98rTXj){d( zx!{N#1b`E-ASjV2STNs-V?vvnMO-Y$kOjv8CE$g?MIli+k%vt*(vVA+tHhKw%C59^%(A#@*1+z_sJ5abm$i;D*!7{1}Foc-e;+lpq*9 z>%kaH%(jVD9j#;IBMdgNgbag9aLo9opu%}jZEWv$IHskteg!Dg zx_V6y$T2!Lx{2><@?lM9es4(8OMzjJG2Wp8+KdG0Cxalof8>~Cz#2xfAQ*XRDViB& z+)nC^Q1vK_sGKySRsRT9wn|rRRf^M=r06Wu;~3N)&%4-Nc-*1ca4-)ZJm51T{9Y_NaE$OD) zD+8aLp8BhgZyaA&^WVRF>95|LeSNT&?^o|GkKXHxI#CsOydwH&b=<*hFGb`)5~nuFGBg@Zjj*KDhZ8_hx^4 z=lHL$?!7i#x5XdD>r2-+)cy7Qv%h`)$e+J`>Nj_feR+QJ+QzmKZ`80ic3Vy6NLk{g z;T3aT{%wV??qkuK06UG{TM@ghEaH5R|Kysov6ATF(u9$!>|N_ulw?L5drV@a>@l1= zomG1diE=hj_Hxd-F@dmVetEK#Xi?^06=TeFW4C(>$GBOXyBdz+7DcnTIYzC3b|EK@ zaknOMj2fWroovrQL$=M?ov3tW(Lm^P!koYbiLK8w6W&|iig(ggh z0b+m>jWH2olVLSq=DVCfdv=bvv(&F47?-DV-p?jQo3jsm5Qf;%`SWC5yLJt-DK9Ty zzI-|3O7x97&xANmEN7UxdixKU1$oWlya#u)P7Kp~TiO~~JchZw%x29DXeXY;X> z2S6D(X6ED(I0j?Psnavqo5eAhWH?B!I}=tgz(7c#1_blSJEK33AjV-310TWJD!~ac zZj>>Wl8`-yVuBdiQ7pAslyMgTq(m)dc8ud5L5!6Oshkh@ns4`F^1(0Ky4j2i@PWI* zq0z4O1FJfFm$!D-w|3UGbksDj1ZDW{QfWnP?edoH-huw1(E;Yk(Dy?Fjy=X|BO^E* zLsLO5;Uq{u5rPat89S~dni+IVGBh*W>X31dHguGna+OHs?2V(~$mJ{tNOKbnZ? z)!h&(#l3f>Xj=;4R41Vxwk)+MYI7y9q5XB*+#Qm|&tLH5=p1pqbm2Hr&RKkHz>Y*) zfMQ%|uD+XKEa^&ca}2VZV`%xzHW0x)iDQ5m6ayT?6f@cd`?`PsKK4~!{XjkN48*L3 zS6+E#@#4iVzx*=uG@0|Ox2ZuHoKclB4=ltnXiDWu>56;)c%X6i84Q>?jK@gf*eOh+ z(dV(Tj4PRWzP!5|ADx;IQJ5UDwjzI^B6mlV_sYhOZ?5dWwx#|1OZ$E~J9&4g_DD?< zpSIq`n@Z(z)0GKFs}uJ6ma)R`>BdZ6z-IOg>AU=iw+36ko!z^=Ifdkk5y)DuFhl@&eoFHUF8Wod~rL=W2dSUwpGUOtWDcoku)Ai9SvlT))j4C z(^Q%n%lw$wxFzm!C7oX9=Nc%H5CoafKXHt*=7$z#xHPzbU6gU}or9VGi^Ar|h{)5@ z(!?>0E5YuX9|OwcfEf3<5=}`BN)3mGMth_Is*7{CXm@*8)3)7$dImy`C5dC~xDskr zMgj;1N7NV$_5>GzaiffEGj6j=2wj4f6&sb{m|%hdKtrNnMIZufSOFrj9AlY=L^%}$ zT*4f=LLae?g&SwOh_RQT+Cdqyi$VbnOe3rjf*@0j!fbNk{CV?L0_2$)PzInOodilk zEn*i!aSR!%0do%cLU`%QmGc)aAl$xv8@o7D z*6qar1II8ehF7nV`-j#Jj;x1ccI@5+$H*RY;?z-424f6gWj}TLB>kST5*Z8B40j9D zU$DdwG7R(xVi;g@=HXiGcqF*zsW_h_(A-{YkAXA9C~l77?!_4jvd$TJQW=dUSz=jO z2$^I;wwc^TJkg^&9mtp%*f8EZw4r%bS8Yo>9-3)rTf;;de_dmswz0LddtLt!-&_JQ z(DqVM?r@Z$Ii}2nl$KPN4OPB1eh!cj?>I#lCS`{d^k zwFkCfNyEpc(0%c&W)vH=8bFi+qZYoVdA6qV+9ss>Z7b*jNe7ZR){4ykFgvL2p; z4bGtmWhBKXLN>%$b0s}#S$=ZFDqmKwKWjsI##kVE-|C{nUEU+@MMqZTK`;hW0`YuJ zX?q}*k1I`8C2ub`(W%PR$ug$SBu(u4CJq%wPgJIkS0(oqM~s!n^%pD| z%3roV{gw8FAFYU9)SJJ!JL}moUrc||(tdB`n%tM$vtC&1iEPbyX;t3R_S~f_^CG&v ziQC(JWAz2YRT-UGuZ;N;HMoH(1rg~MsDHkxZuE(J;%B_SVY_~@dwJ0QOg$ePpxkLu0a_gFF%3nP8h~9 z+`TyNZFB(EM3h`>Yb%r78B~%Ph897)z|m6ZSLrI%{nDUtYKgQ{x&qsHZHExn@D(M5 zPM{V-R4K?J=brLH3R!4Y9I_N`7=-{LA{a{~mOK!w11YQwXIKP5*Fp(6;euo(Dn(c$ za3OR|D&!j{$ek;TCFertV^Z zK`^gRA2|ZV7^ZO?$Z}%#%*>h7$4;F*b?&TW!jorb@u$z9JA3iMg{xO)FU(!Md>N*J zX3ovc)z#H;iRl2jh@4nEc?crpx-fxH9AmySaA*(nd3*Z0;h4^@b_SJ3#`=I5{Dz6X z$*GMqrw^SzchvZ^$4<}A05ReiP==qv82}S`Af!vgLm`^FYrf;?%#v{ilpf7uvG@Ub zINq6W8{!y)GTwYoah^Q2IdB8H6b6kb4yrtcGNDl_pocPsPJS;}m>=XAG!PWRYe>W6 z6RXzt@O7oS)>RM;vt$TsR+yFX8rwS7GNonIzzQg%R^e7lq+5=0cq167Em4w9+!{+t zOB^E=#Wh2Ck|S3&Qi)pyQZ2`iQxla!)!`A^BUB1e6{9gDNHL>{iRuWcM=D?H*&UKj zu8O&9R-G!Teu0p}*10Qj%M`F%K@4m~R5iF!L(fK}2p}w5NU-}tAVrnfT}z-^{c40T zHqxWjzsNDR9(%wDHc`jGF2YWZJ?Es$g`GE|^KS|IT&}g-aZ3cP6BF{$5|V@wr}vx-@InssU7`7R+Z6#tRl3TSy>rvMO!7G-tNI4wwvSX8;NFk(uKp>Q% zMI3`|0A7(S0fh5A z3|Yz*c?c$q6~+08BU!dWizdz}(5%@7xlCAbJR4E~CxJ3Bh8aJiBFBP4F%Ai2!G}Q% zb6zga&9OG_g-e&_u3Wx&?drKp7vUI?MgIKdOL!9T2$!y3GfXo(i&X~CF5nm(m(p?! zr&{xexFWo5!>AC8!R%#<%>G^2W7hSoX!X+ye`PzqH?Yl|UBD=Sptuy*b)fXpWID`!JnmHGw2MA)|T zqi}!{DQ^*k6gO%}rbAKxB6cCPWwbAVxz9Gz-&&PRDM-^6rc=Z9qJBI;JL;gdLq`++RFY0EM6-F94wfgy&9 zu*Za;#r&t=cRLh=bRKV312KF|AU+|6F9|G*UV=|ZV%a*gY8ho1QHpbhZX9?qHh-Md zA)g5ptUNNzC|hC3PD3&2Cvgl`8RK2fT5jB1Bddt?E_;--iaCs9Y&zpgkPU@3u9TOw zwAq_BP@Ox>7Y1rmddgm1SNy_A>C&;1h=KfpZc&m1&z-1$wIr z*Oun2^Q1vDn*xd3D&w{?d8I0W^?WziW{%exKUST#r8awCYw6_jf~|EqyW73Td+Vm! zOSi1>9PVp4JlM?AFT2*%Om)@nSW~xYRrN$i-Nc&4@y_Mzm;1(7)%P`&O!X|^y}o{D zcg@tgI@Y_}*;TQ1RoS+Vik)5cTUOU>T3J7|yn1!O?@3EaO^m^|#OuoZDE-Xfxp4l8 zQ8-J=1#9F;4~fCm{Z)War_=%s(BOs%OBKJj@Fb2=`VXki%`rk5ZUc^!+tuE^+{~C5 zaopk79s|cPuEdCv;9l**%`vnW+pN?8!}>RM2%;7mK7zUhWIf@8*<)mS5y23mS#b!Y z;}GB&EC;AtXg2KcbfQV1zP22t<@r@{_+m_!^h z$N}pR!XE}fFrPS1#cbBx+#HNT6hjLJ5<=@qCzow6T)<#*5le}(CD_6jptCug|xN+n9&70Tn+`jqxYZtFyJ8^dQ+~rFbu3f!y>*kHuU%Peh zF5%VNw=UnjflMN}^ZNZa-+t$vyKlU~#SH`kTs8Vw=X4(63?p!IIK%t)?`8ED=EuM> zd-m zel_crcdqGRats{9%hHY|24l=4dyLq{3;hTu#H+jt~U68$EQ zfn9_$2&^+BSP{)wa6zys5^NNRp>g66P=w~VLryTkRY$OmmP}-Os6@%dp@s>ihH1<= zqRJ&pPPw)WiK<+6+Fc;1LJCliAi$~eX+dxw&L(0ALM19{VFJO;F}AOfKw<4hTOsQ> zb=YBhu{BetoWYh5xR64fI9n&RNwz1!R!h3Fvnq!#2Q9g;vD!Wjq#EJADFA>#lPEFzB}25@n^g*YY%F%HLQ_`uZs_=dt48%o`x zeR0y_3ZKL=DM?A@XD213rX*w}MdzhNbyR!z^tJ9=TfMKVY-?N2{&n6{gH_XAWivgM zmnK%8=&3)^+jM#Jx}$@wd;3@H>~Ec1zj9;y@?9N`$NSq3cUQ6i%<=Vs?TtBm+DoTa z`zIO;H`L{hHRO-i6>Mzqj8x^UElunVr1g}i_f}?gmZkR96||S8tt?AlTV1%aG^4dN zv#~g>t|-0QlOD)V_GQNhauR$Q(aVdIYx8323*s6I;~NX(mlwuVXGPXzFRRUqt<6a& zPm3#vU0M(ylMxe{krbO4$Cob`w#Vqq=;YW-9Mt;BM*Zt@>!ex4p}bBkAu!6d_jbPQ8|TDm7k0nmo-PWPw-YB%?CLC}>OsSy{jlB@z|25TyW7p$wtXupxVlhy*mj zBm=(S!Z1bf!8j0B4IEJs%*>3j!4TRg*a3pz$dG-8@&;8-o&;a0S^FZ9GJpz+IC3vu zWX$FQAr75QJ!VfQPJkvjvapx1e(vR~SFc>V#<0${+qdvHZrw8caTC6{#cUNmop|rw zJ=o&jn{VP@zjyD>8~5(Mb^pzGe*Dfm?|k^-haY|P(R=T`_tAp~pML!D*I$15_19m2 z@!4m*K=9U&fBeS%`)~aC?YG~5@0|x9zWeaO+aJ9D;isQ`{?niQ?3cgz?%(|Co9}=5 z)@CjyEh&_w)^zCBj+y8T)2E@?$YUVbH<-N zcN%*PCxJ6|c={0E{DNZ`S8_p2aF&dn9|L?8d5ZBt7vc{%#+e5bT+qdGjJMP*Dx+~F zOD9j~n4mpIGhkd+7wy+mXg=S|f~CegGlC^A(#4>iO>sFIoan@{`+C=Gu?nJU|c{P4=*%9^Nv_}xlQR?r3I0zC;|EWuC)=e{?P?d_pld&Ri{>|H^} zP4`X5O$gTTNQynCqM{-zD+>jNquMte!I*>p2nbdN=m(rF!n-%+FYUCn9d`iSKX_3!mM!lR7{Ypmc zl8m?renNV3Tv}3Ma$-UfXCXe0FeQm!nuJFn9j}zM6z0<;D=RHE5m^NY1vi``a|6UD zFzX3oH80Rd#}gVCx(6&kkfy6+GM#I!EW-Jh)mh9r0sz4yORyo=`iD4owUpQH*tKxY zatyaL?<=82FgrAVwe$QCcMBXj%TsSRs7#t+z0cyz}0B?|=B=gO5IX|D%UL{^0%l@4oZad+)yU;Ri%Nc<|ui#~@nvrow$7M9R4hmi7%Wvf9V`kc(5mN0uLTKz&BVJ zWM`(Jvv?ivE16Y#HQN`QGOoA;V~qLlIKwoKGcgy?$N)1xQZ0|J8xyHJRGldW1(@}A`BX6ckXqxvbp2O#)mdc^bTxT z)!o~&dR;?%cXMZdQ%7Ij%I-kZ%A$(;%I4ON^?lfE1~!b)T(q|Df*d1lM5tDzD6*83 zw3p45t|C-na?x0Ba8XoDBYj3;Hg|IjKf!8W1fpROBaX4SLm8{}5p23U5#3BNLK4yR zIF(e*c8@A!i$Mu0EL_l5gi5#dOYy5_m83rjb4p(@G=`MNO(_f3KYuUo+W3H~K@-P} zM7s9Qq4JCDk7BtX$J3_95!@UD&B)opoJOvTxxS+#Fz)@oE0aE$bp^X!@`?Im_W-|O*Rx&bADGiuDGv=nuR(r31$JL~Ckm}U~kSd~Vu zY7VhWj6swj(4b?ZEXRN{I(~5sY=bhE7wQ;}Niv!qrJkA;mzk27o1TO*qaZ!G!S87- zPF-D|*U3v@$0?Kkk+M_*V-n6C2P84BDLGqHE zgjcf@mlUQ)7oD$*+?1%ov^Y;@f+r&}KRqEgB_T68F2ey7VakFb^p=s9nwg#!^cg8xnW^}UbVD|d z4_f9pQ8*}&2~I*8KJdszbX&^=5V|yE+3QXUmrPfU&|XKw94`OIaEz+eeWJr)?_7Fr zSKZPMnVWGX`f+g#iVKbbU*u>AIB^W2c{+4DNtzqYkj{<~Yh!fhdBl;y7jcXThL9Ct zAQ|?r&7?cM8FY+nv8qCbB3UHp3=d;oC37D@p}u&EG&CfG~feD@s; zC+|Ic0G+)1;6pHlbT)xhfD+6kVv&!(_#6**82|Za_+ZK>pTIgm4>lM=He@T9=Bsah z_S2t#hsWH4Y%2N5*I#}6%}+@A?prtptU;i*Prv$79P|Be{$$IJNnd3JeJ&j?9K$D& zwr<(RGFO~c92~#wP~G#{2vFJ4ZIG-@SJ;9CPOE z^w|r?vBzAxdiMNK=;9bAxD1bO9NMsPZU0Dn zSKo4mmOA=YboMV_y}owk8ed&=psBg3y@M5g`J@0Q8O$)OhDRf@L}C?^6qVAYlgP4( z>`~4Zpvf8K=QxD<9Ai-i0jDM^HL0rj2`EuHWE{C`CV_|sAFHG~rJ1AqKB*HNm9#WFy;h6NK_?)!F ztdw|ACO|nEbSug0xs~cCt4&r6f1CBqy~rHx2L2PA$qzF3L(O&QA8_XB6kAdUMk}*(m`} zc3FM~DcyEPWAi!%=48!Mi7Hl#(cJ;zaL|a8M1deTSC)Q zZQ5j>S9!poVQ!pY^1!C;+r~C;+PZTG%97{)oqPA-ckD6vVvR9i3a~=@)c$>Y4;|b; z&4d48gxv@B@7lMQM6y_9mrWQ~G90sG2V)KUGOPoUU^qE5cOK9CIC%4J z4nsMZO0HiAJ1~b}_P`3l3=-y%AYd24GfhMSxp!WF9oxxkcke3EOfF%#=QT6dgS&h8 z?wfDE3AD`$v3_de_b=LabbNzz+V{ zw|_Sr!S{gb!T3cI}uU)%(e6(-V#NhBy_sHY3lq>xSuQ5*_M0wIaosmf?`<*K|aE`&<7%1ru9%8W!dmyT3z$h6rot?AAZsi=%; z-k}wKrL&bn8H*;Q6IHe3y0a{}*upmDF#>Ruz0vZHlkT@scS%8sOe{7e@iFFbz(J@% zNG>61s+K4lDlu#q9GjR!<=u4xF<34sZ>vSn=7c!2;kGTT9jSpNodk~jQLd`q0uTi` zhI3_4d)Va&i|W$5ZytLKaeZ+XU#y^ez|Ap03{Rz&W9aLxlNyk!LPjy*!kFXtjXp`q zx$B_}n#rmq1j{aVbIQ99#yK=+E{MjG7*4VtSaEp8gh|ORj~yn75fnV;hs?C3tkfjz zF+dC`lb4Z8J*C$qdLtJ0fOQJfv{WDzaRPlrqVh1tHs9DiYM zxhK!>AGk-%#l8}cueivh7Z;Tlc}f^h z=Ls$^moH~!^S$%zObj?F>8Ubx*pL&<-NL0o;D*8J=Fychm(^vhfmo8j3(}u8fVb@vTvyO44 zKn08WnvYk@>rHISF(MDx1&kq4=|q)o!XL~r*c7#un`6wPb{Jz^9AhxWnchobl{C;3 z;uso&oZ%Q8>LjRO_|m|{MmUDGWLUwM_mx(3^onB|J2A<07?fGQVg(H#$ z`U$l;AsOyHx_3=hSS6bHLV0DWQf*Esf&pSI$M9nxRk&pvrcUeO7>qF+CpPiur$rG> z_ynh`psS;M#@+zB2Q0+sazBY<7*S%9Zy3j@yQkl`+6aAsjAB4TxPjw`$ZqnWyrPy% zY)V*F6qCBr6S?+l)uEznqV;(dYK=Sd0(Cq_m}D~pBss>W>IcNNnRed4GbHEd8tXB%rsACDwdDZyeu!Kk-YTcf(&nA zwgjv2&M70rSW=YZE6VW~<&+oaR(SJ#o-BMtNq%K%L7*hB+?$JBRRW0Q zReJLS-aLwx7w4B3<@-E&WsXMxT<|arS%KnwUr`>u+*{zMqzMZu%RE)S;)+s_@g+s& z#(S;zc?#x zhMIBQR2F%Oa<_=0?ENf(*EHam+S=N-wl+S=!4zLSmKY$$7-O6VNIEOJ0!D~1nJ^^< zQws0_xWFGE%k+tvgU61ZJjZe(r;eXF&3iPb&Y#1}YJ$mxIVi}C;}Dwk3v+W?Fd2a{T`#4y&wToV*L@NxI;x94>0Stj*!@$9V4~5Emvt-uw4X<3=yP~rPV@%VU9(=>*)mq9upYa$6`|CaJG2$DxtxB5^rrSM+5S2K2Q8d*LYyTD1a0Eh z(ZoiwB}tcaZyqMAJjKKr+DZ%&+S>fLwbAL|1TnlgU^zx$L6!t+kYGdAuXNdC zkaaM2M>a~9oZTFIjK-C0I{QKn9=dRF=VeK&()!`W2s#UA#+%q#Xd0@5u{(>BXh6rPh1*1l>gj^W45S^bw zSz(H5BT5As351rlUrH@L*(MY1;Pri7vqHA<3T7b$n|5i@BkC}l_j3avLY0Jg`@j@ zhAIpzAoxHQd~u$iu!wr{10@9%s~{}(RQf#Ces8s}2>vkSQHt@SpaOa*3HjmzKd^!k z#cZ2vP^OUm=9U|R$pu`>9F*bMklEIOk05_IrWD7TQe1>J1>*|!2TC}$JVJa$DaXJj zj|AmXzz;=v^Wd#Ylgn0xpb~rGgcum&ZBmxx@)Y7_vZi~aAI!^zYmCp$$z$}1b1R^M zX7H>o$n;=_@vzch%`+$yW#$Mos3erJ7)nZ*7uLueV{d~61>H-!*N}1C8@ipsI7XwT zxw*N_kHH>e#+ACdm>tGMUxr$N7|SuVV&nrcrb-1F90*XBkKYNhTCu4(~H5^cysvf>-g)h-Jt+uC=B{wSz&gqX31dkp&>Kb z0)o-Er-2w|w@?ON!N2wXd(1w8WAK`i0(QVFFodu`A>07Rh*}V!4a#7)(I%u*30?*m zEHT()u*u*lMulXlLMTM$7Aj;Ih!9KxM1(K!4Y_y<3q*u6k|7(ssllo=}ly>^9HwdUsLs0ZZ17*kap0AJ(*8psB3rpT0< z5hM#SZhH*!V$YB?E_!N$DhKk%AW2`ds-dBQqjB~ya>5M=bx&dXJ2a|$D;GSqh zs-5R)IA(le%gETKzTr_!GHqSVkLhXd?px8-+t|5wc}I6yU1Mo=-HKJ6U3@zdiwQ$f z8;qAik{&`9C?KGgNEExU7s-TX14go3b7EAI5FI9Ug@AKEk%yrSxvD`GQa?XOyG9_2 z(~gLWEeIteh$N(%*@_hFl*qQ)g;n2dB9-sn*5+D)dXOmzF%SwV+)-PJDx?@)kL)p) zV}vh+a;nNAhy-`#6jM}(VRu1P(54i34Jxm6LTca`C=mRa?)Q>3+t>cWkf5JNjGxSj zm2=K}@OxX%MR;Ps8Rpt?(d8unaE|Hg@8wCNx39;UZ|`FQgdj%YAI~u;73m%XRErdh z5)~!IM#C_L0%Tc7NvS0>T;bS!8eeJ#TrgMQ0Tg-EIRar-iKnKlxVp3m!3^S*c&dvFt4c{M z!dI0TZ-#Y18HX*(iwhj{i3zc<05Nb+6`NCuzqrOt~opBRe>L;^QJ zKc$|WvcjAalf5HRP5S0$X_y4`FFxj_fF47T#D;oIxV6#u!%s zDaSj5P=y@7^`zjH>kMOM2QVF#DK2!DPv=2<#$zj4{T%{~k6Kc`*URAdEo3lcgvY z4lFTjuJ?wh4Z9A9glEPK{tf2yIxiD3s08a6&x_E`>&-Hd5JDTE2Gt5UL>^!bdtvYP zV34)zH?XXLL}Y~wEjnhZLcpX1Dv4&;5u3=;gEd85f?z$=0+hHRh7_WNZisnlHN!Vi;vtuNP_pX^A1AKG2eZ3 zAZ7uM39^gBH^>%f49*l3EHdxlIWL&d28`-;=4noB+&Vh3#h7FUM^>%xZ(h^e($$AO z299a&?g=!u_-dEeG`6;Nbgl0jGALu#jS(#v`wR_cw7GRWc#cFK;}FMAY=@VgWxBunWiT@Fl2onnfTf?$5W z%Sk=6q3TziDv7>F(@Xcewg?xgK_zWr1S@NEg-RDgV2PQ}F*3AhTNSn;HRw>aFJv8u z-8%vYub*ra?dG;l9f?4SBMBA=jVJ|;G0u$O$9|_{p)tA6S>+^iwu6pAr6-Rog$g~< z9uszz73DV2onY-Ta10Q`WG%ihz#>j*&Ws23`-Jm31`Q!6%^}%pCM%FGje?G`kJMJ# zDACqnb(MQ_TZ7#Soy74lX;+LTorH-cJrjV*%FfQlDu6bnX*=q+xU95@=^#GGo24B} z4Za9s%1aEp05O$*pHRk_F3P-Bj6mckrwex~txPMFUamXV81B67BuS-l0>CHbagNxpE04Uvs64tZ}L6M?gt zRU?lqPgDYPs<}JV&<1H@Go1^AM2@e+PQo2Li^FlM6 ze07UF4gxX8L}TXCF#43v^dnx3;_WA1?Z#x5#OxUm)EH@a%ZwMdd1v1IbA~OQRTGVb zg(f&oBvK*7J)L9RHzcxO(+!8Z}egX#qU;(FAF;>I3Q5 z49CnI*W&kr7}x~?GYrE?3>CpKrvMtpiFgC(+SQ9UZ{XpWD|c?QG8@PuV+;@j!QhR+ z3|!{n-g8!OyLA&%!N6lC{POjm{ree6Vm2-o1Aqow0>eol2=H--SC<_l3LJn(RtQPJ z0eDcu%0xj5n1e)FZXh9m2@?^X3Lyy&K(9|T$(NZn3^4JJEJ{L4)BvndjQtV{WdueV zIihCDa2R9>N<=f1LAb}EVmfj>1!O=%AWL3{DgzIpCj7!5q7W;HOL!y6dS0=%FDQ|V zr!XFfp%Uydc(_Lx^xyu~U-A+-9K*l?R}-ZGzA&x?$G{xO&f+nLnV*ZWbJq^02Q<{x zHZ|6*UfJBSaz$Tv`_}QnJv$~QHxF;$Jh*@NrVD3}z%j4ixgvYatvlCl+`N9tnIFSq zeP_;`p$2BdR8;zn8K$C?&>twNtoB#cl*2cm47nI)j4LrSf5V(@M^6%HSv)5^#xah; zMjtNVO(n}Q&TQYuzD{85E)KzH{;xO&0CKE2CM(D>-2LcwytFkhtdDKl%x4OiCBuZ? zmTso{u50dEk4dIs_1fy@)m4ovE9#o-o7&d)46-cV5Cp`LgIc0#w)2GUef){9U-@@w9;2r<@Z(k zO5~YYQtf+0FlOi{=!+`K@&l!LmA-;1pBbZJ{KbsRc#RPSe8IL+0Ru7dwkTg5<1fhd z@%1(VFG}cu#)m0ES)|NL^`=FVsa!|%p&ft-m zTl4=@_8#694-pzsJJA@9BS-h1!8M-pBb;f(-+@LmGs1ri`kK~>?Q3{VA>qbS?e z{rYw9dvAMY&YYc{*|R%mcXt1R{UUx>$t|k7UQe7Lh>VQPoA)X+;>({4g((1vq7(F4 z3Q%Z4^Mw_TGR?tu$1}taBOYa=gQZTWzehxnx5=i5K7l^UxX0gHOnHF!u2V8HAZ(L?j{^mGny?gCheX zB@r${@taVALVbe+e1iPF1O2=LIFGL<+203K8dto*@eXst65C;kqwNw$J8J?XI@sGt ziT}K|2Il@yw}#v&=68-X%55Wc=_9v|+>^9$=a2wjIEE5sqRnm7&O4a(4)lru27-ZOfS4YvVNfk0n>lg(!0D5R`_CwS!}+tv z`uhZBC`Il9zMLL0Ws%CjH;@FHCe8`3V8)>wowg_)7IrF#XE0DD#6DUcr~;Uvvk;8n zi_n7rgvd?+3o4SSO9nNR6bI4E=m>^5m|Ljg6smVfN8c{z7jKO41SxIw$)+qTdxgeK$)^yPzE(qW^olO zE`c%yMO9U3W(ie*L`FM1F*$KIl2n9Ij46ug3R8x>yuA4Mc;uqYL-aK7LrOANe0cxG%wgeot`8rMvFAk-#7y;B$z-rfXZ9c^42Du zX`!3ZQ|jiWun46z$|hhTY{9*2Bxx}}mb&@j)Fsg_S0WuKxe~s<`4^;-M1SM_Mn!#) zCK$lQ$mZbkOO7F&3>?GF0>`MVoY!<*L{NrbkEDJzowxutjX#9xPon>mdw{+=6B$G{mzV*Ze1OfymeWsE6Du!cj7 zDThO-GY>KGP|BobyiCI`yh(du-Qw+y+y#9FZx~9Sp=7GT#G7J%Wt51IicX4)MZS_0 z8wJ56CqyL0hbP2_#>a%jMdPXyDn2+Ejwq8Cl`$p3D@Pf$V%bWmv@qH(MBzdpG701& z%G4rn z$#J>q33(Yw1z9PDxoJgtY5CbnxfuzWsj=yakty*JiP7K@<}88QyjL0Gps0!t4JJpa zGAKOIKU^`5U#Pz_Lq-Y3rE+1|CUb4UJ}QU$d8>+-d#I0Rn6FoeuNM_5X~!{JQIWq7 z(wfKs-!LkE-t46(d&B(v0)4!L{d~!RoFu>}(9hG?%hk`F?!^cNmWD9?lM~4z@0irmWz`VF_3x zE2SIv2^Hg};)XHmQlW(oa`VXj1BH_Wd_fs*A&k2Xc}#wOJ`WBr1Q_|EiRa1X{f7~X zjCvTbP-Za)db@Qgwz`xekJ)qRpr8yK(|hW~LF_;KPAi&$7|x$NJvbm7L#1zQgxo(q zdiKKD`Ei{!$AAdf{K84N2b+AFy1Oxm!IT)3VGhQC1_cl-A`m0^B7zM{sTlZTUI8h9 z29823gf+3OOvDOA=vhD+K9_bCI_A6zvpY02#DA)$6<8ws;pBWSbwEmhi4$^KK^);2 zTFB6hNL=X2Cvphi5qv?lbP@k4ohLvmZ73ts7dQjvP+}P1LwjEfl!$NzE)jtW6)?rX z7m>smN+olSp}(*ZrzHbMe9)5@&tXA?vHUgBEAhw08irtl%G6h@lPDn=%B|Z7*|VNu z8IH+FPcAOVCYKdwx3$!4-OO0tf;?v9y7q&;+eNQ5FnH=b9_~Z^X9v#po$Kd^l*C$> zVhsbkpjRS8FzA(#%80cu(r%=}0x{DXCS@5TOk>`n^xq^MHxGjOO^)G(L2yLHj0sh4 zO4Am;D3#vmm5|?@j{S1|q-V7-nn(Wta%z8w_PcBvaYYTv%0yJO+-* ztEkT{tIsK|OUo{aP0mWoC@8C}t8Zv&#@A1;cdh0wJzX&;8BijV6D1EGa}pXQPzLQ1 z(~^LKbe0M1-z|+~w%6bl17bLXO3R@ZV*4s{aI(Uem2IpPFPkd-P#cSlYIzKSg*w`dpMXQ< z#xQ1xYrAU4A{g7?X{#i+M?B^D|Ia9D}Ao>lFB0rW__A>_$-?VfcdDh{OwqJlF_n zRgMgejt*5Sq?ib$CyI{3RVNV*5z3(0ki?i^L@BWm{?QQu*m;C&*#_c`sNeuH6%lnr z1)4N3*!C(T6?$rU2B5$+PaqaDj!PlLQ}Oc+!_42?D>T3_L{K15o8pE9;0qlW7Mu{K zBs9or$Vvti8JZd$o)H(7l@ybgmROvfT9%(#S)5Z{mRD1eUtN(`S(;r|lv$jYnwOcF zofeys6qy6Ok<`N{fn%2nWI( z+1K5J?C){^g=^5nf6XfNkc*WaW+9_#QCjl2- zJbm0feLcMVJXP!&q$x!BrPbHh-P7BZ9KdT|sDDUA5Z3|6sJBd3m5DSBixH3|E5d~M z1uHi$9}~m`V@a*D{1x~^s2u16dj)#CkqOyH^kLS7a&cVZ>|o>IV6C#f4L5^vlW@bx z{liVgT_-o2aYxZei@`A*#mz&4V2lzm9tj#IR8me(4&xH$hZx5&05a8)7`J(O$GIA| zP?6=190p~`h9pJ_V-6jpMJb!KUI~toEHra`KyeJ(C5V9%eCfL|)_-yQ?8Jrh6Bh=w zhy}3+@|Y9-eRwlLEzk^ZP*@PNAR;c@WRzA|4Z|_Ofk-|m%`>P0MhL!$q6c{inHH19 zE*x|2ES^&=qlol{C7?|%+^icwm>CELtnu_=D{hM4+FBZr_J!`ugs;gUG~%+Mel1GrqlRSLrzT$3;g#>f|wUL2RS0!X6a zVa%%{%4mZaLl{E^Mv-oijfiAK24g6mfED_1ARXur#K10OTG+)VSBRZ2I=hg_2qkD( zv4X!W5QF}RWtBt*)4hAgw(ZK}n)oqY8`t5ll$nu|nvy{L7;;%jPD@kO`nBz=S2i#2 zs6$?JVE?v(b4Rg{fn!iAfil7|{D3UHaDL$2k)ww*GE=dS0bj`Ai^{Q)qEU*CLjo8B zoS1k8E3*ibAd?DDkST*XT3TbyF(Ri?@)#|Nk#gD&#zZgzF?d{0w=3xjhX64qF^?9S zf-Dj#n4rV5;(^+X_$`i63MQSHsX!CdMpgAqrPU4j6*Xcg1H@z&RcGW^B&OxZCuZjr zRMgalR}#$1;;q8ZA=cRLq)h zP2n^emn3zW#f@(4m8q18)_?%>Nmq_iGq^svO!o9N&hR@GV-}Y_Y#QgGMPS1GRMKM3 zB?hUmi)4Hj^dIGG_06ZNG6mqokAK-G8iR~ zS*1}%W6fI}gS1l)qU4M7OUmDx>yh8wD9!)e#%*K#eWgYI?xIyR@L5x(T8Fz<+9u){sr-;0b8;;oEKLT6Dk1yyDLQ7ykWFS7$SkYoVgDr4)YD{EW zY*cz|WQHoE6u!hq=Oo4Cr^Xj&rIhDq)|BQoR2H?=m9;ljbu?Gw4bjqA)=*PaTbW-` ztY{`bD={Z6HY+72D>)`JIW{vno}7`Kke-x~nh=+Od1_cVpBseb2|tXRm%Edj(-KF= zB@Q+Vt;yC4tgPlQwwkxda`pl;6xGMKEEkihSS_$5FIi+oreZmFK6&x{h0;fL zn7^3wsM2z=o1>E_3pEhf*Tc!(-4T>=^{{vIbnp#u_Y3w43iktL7!BXz7?H<>g$0C$ z`iB84A^zc^zF{FgN}vVGAUz6FWvO3@rxSNIN%`ppQAhfHKHqXhEunIuee_&CTVxfasxn9xjA2ytpg*Clb{S z>v6Q^g&u0bwwElHF(QniPK&aV!P@tvf|&g$l~hJVGA9PlGnX42bME3e5F?p7SR9_lAS}U-m=7YB49?idV35Snf&&yBgL#U`Im`)$I>aCxV`z~Klo5^*7bjFjfDs%+ z+&nCZ70R&cA|}Sr6*KS9kWwn4Q96Gf@eE`G%8(Jjm{3M@45Xq^W>UrNl^8SP?@doc zIM|?oVkoMR%D`31@`lq~zGSeApbR3JNz87v>yttdoq-s|F`7s~5Qv0Kg$_b0UWJD zzi$1S{Jbn&uUVQPo0pA}oTi3~RV$jv9c?w+wyZ`TGc<5~c<}Vl@R`BEJ~-yw;CWDH zU|<0C9KK7v2ll6Dq~NcF3`RIcNo8V`Fb0j1aEw5VLKQW3Vcvp$nUZLlAO@P5PV{_h z9RpDeO_w5cc>^&bk5Q!(#wdBruQ|q?U<6{6Fh(z|t>iJ>`Ajg(cw!=>tQ~Yh1c3>^1)&8jU{26iW+< zO=Fs;PK#U{B}vXn2Xjy``v1KO=ixv~j-n5BPAe^P$XjQVO#?4r3n2_zJ{(j_@tCmRyTok(~ zORF~;CAntvi{X0sN%eK9f;xXAN!0nP$xUMZ$2D#M`MU$M*jk}fs&A;NYpANLuP!Ri z=K*kY$8A}~h5H?j5tNasLhABzY|Ja>5JRK1OU1n8SYa21FVi->MAwC%WU^6Sy?DL^ z1}g(zy`BiK7wSz#>yni#qkgL(R0ABNdKcjRj+ERTiwxsSLfp~dyo%Ez=8yJ9xnDC zEHgj=KM%ERlqZ>Je`HiT7_Lxpws$3nF?-2wP9D_VAQl%lJf$(k#Yz|55N0v1t{BYP zxVqUoyV$t7+j)99dipr~1$e1(Gb}K~WN&El>V#uB1bjgfBk~v_7<6-Fu2>)j*2HWG zBWN)?4)yUsHAd_~Z_tdDy0u6K?GnD)#!bQvBlnMxiuqk9?Z(~6A=H&LM$2Qs7qFO{ z3X}nk;h5Oi*sQE9^zr~bj|`pxxaJ~>VW2_LgTcy{T{{I|5WW0@V-6hzJ3twOW3Z0_ zVi3llS2}|2ry0j6z0!rTGg=-4%D^#*WS|oTDB5xb$N*fB#9)g9#~|B)U=YS&(E@NF z5dkAG_?5^micU1ah+zsqBk~wDK9UicAUHu%LQf7vi-bKdx+)|wpbSzOv64Yh1iLT; z12H5eQPAQU`Wqk0;n@FzFR+Wkm+^7rH*k-H{UwGT6*B!XBIbI47&3^4MKekzkOhL7 zxOwB!d%8lrJFJ6mz6)f)C?bg=%pDvf+9d%R2u1`g0yLsmf@2Q<0qdGZJBimWEB|xxI`LUyRLK7=8X^x0b`KFY~Q(g_ud^_w{K)| zCDywxFE7l@OwKRN&Oql|l!@m95VNUk1@U9B^X=KQ33<%O(3z3Z{-L3M(JR3*82N%S z$YTy1>`hBgPD+l))K?Tqy2Qelmyc*Ajfsg-0HY)Pimi-*1utU+%~Q(p>GhcCCLAN{ z7yvqCgJ7mDV15H)P%usJHE|5mYtbu-3SOiy2w=b$6jDYuaSSsn_+n%x9%daT7|=kZ zEch;=T`H)khhtc&0FKEiVomHCWKNQ~iWX)dsmnBG zv>W&$6@eH!zm=HAj6@$!DD$6G(gIOMad6BVwa$R z^m*&3w>If7lQbVB{n_MHl=@_*6B?(IMm7a902HAMHl+_8sJvA--!#skd#OL7k&JU{ z@==8WF>hL?ZF|MMS9s-3DgDeM%CHN0CRu2P5_}=UK*BL{8Rn&NJ^Usl*_66b@)Pm5 zBT*so7Ziw*TY|qnEtHJl4UMcJQVqvIGbN>k+}8iDUWw`9t;BRfGG`a_x&bcqF+Y%* z21OOtmy(!im}8K>;4tOm>kYnOjH%Q}fq{6(DCb_}qk26Nd8Ywo;255Kg))&!k%2)5 z(e%;y_Y>1XEtrR$I2Bsk*bRe*N<1u2roY*R*Y1t8!Q8()FubI#)ETY_Dl= zE^nzTZm7(!Ez7Mb&8aTUttrc|DJ!h2D5|e2ZK$niZmM0{(g?V6@9D*S(D(1!wQFBb z&p~C3+I!^0iT*QZ22P#mKX&va%h~nrKXmZG5nk^J$wmwL#PQR|kDWSws{ho{*jynXA|&70P(WsR^_Uc{Q4Ys13PP}#vTPR`bDZdlIRl2JB! z`*`^H`}zf%-v316t^N?9f%rE?ga(i!!vbTlU)CAz9%?%>Mo2icZ zfZBxF8t-CCpa-TQ{0sqtRS+5-ybgMRsJIMDgfWO-P$7|l7_umpu$4iz1Z^mtk(R{3 zF=UC7Ct+jQrS{%ci&rCPfn!9kWN-`zib;(jkD(`ra9XT(P^(c=2V$Oo`2}*dwCpUT z-)da~y^1(?Fvw$o7&J;i49i3A>DkFj*PB^hY4f^KVZ*tNyvs2-in%a_;%Nx6Q zZdkjjS(*B7U)z7?;K<-+5MKfCcG|e%7Shtu+MH|G3I_Zrt#>~!F7Ls`f^G&1O zyg~>04JoBvPQ|7=*Dn(tq=AYshj0e)z$UxQuh!@(N69YZeDYaul>#mXvdAVMAyMp1 zpQWS4h@G#LCWx6nO!c1zAlaq63CF15zrr!5t6jDNk*N8l%GJ_hRHQDKDm^LrmG~o) z_}MA>6U*O`it$IM!i_}iCOD?HzOuftx~!sz8y${OM!woa=I`m1j48yZFuRzui+Nop z9s^>e!o&o`@UCn=$MB-e1OvnnC>D+(DV4D17)3C8y?c?zsK+~;;NPaDOn5jE8{pjQ z%lbdAE`IJVyw;;g3ey}D=;sjN2hDi+db&8<*|;uQOm?$bM0Q`Y*u&P!%ihM@VTq5U zt*f=AcF{aX8%s}TJLEKgj`B!C01_G!8G?^=OiE&MW=a}^UT#KCXXxZA?v17xEU7J>Q zZ&}^FRpnh38~TiLj(y=GZ+`O^B5mfGUxn&PIK;^w-trHz&C%{9y0 z8#~u@Y~H-CXMgvpzGDL;XU8T+FW4y(Ly8qzAd-osT zz4PFMI}dJ?KYa4|@h6WSe)Qnc#}Ds6zW32n`aHP%@Xqb~A5h+VbeGEeci(%D_u>2R ze{lE4-3Pbs+`swm&B>{&V-u5uD^|87#D#@oP2=J0>*eNbZ--+MS|<-J|OLPGa|MoB@;uASTW?1p0mWeko%ucYGh z>M*|0<8H#qoK)&0AVxR_k&MV=430THHu4t7z#^awN*SatunQKrSg|00LC2&viL7?k zv}!a$5kP@bIEGRx9L`CQ%^30+!Ixif%-9$ZgD?hy!4Q>IAenK6W6=J9EC$CwDsT*B zBX9$|z%(=wT}HLD5)<@;BRNYpjgBItVTA)$r3PX|*@OfL&m*oAkb)$HSFXPQ-n9?j zzx@6!L^5CvS%s6)p=jU?p_W_kzfWcrCrYF;Z?aw{Nr`Ph8NI#|!Wi=1`}akDgH%Qo zPn19m0vH^{`E-63vF71aA3b}@0$AAv`B-;=GF#!&?(S_{Ht%4$$Q@hY7{oB$d$#Z0 z$5IkR?ok|r!8evM2xCB*g2If-s>1fAHE_(j)h&d=>)yVWICx{jeaO^CM$VyH;&&ml z&J~<@_1e^xsmmznF_FQ`dRm?IOO8Q|N{WqEIws|Yt%fg%M}p>2*I66Nm}{3b$MCi$ z1Vd>~Ex%Ep)+@m-jGv}7%`r+0qajAET_9OUov~2n(7(ko%$&@QLI7|~GplE|w5hOo z=#`3Va!YEB&QdJ$D{^^#N-#1BizS(1d$B1!89Ys3XTYE&_cV+Ow`#$U8Z(v zq?>t?V}Fe@(#QPFJkN3}&cgv+J&i-yB>e_4 zNOU+IMnw*P>m>47#yQ#KJmx)({?dn1SOJZaD3xfDIi8->N#=*M>#gr%zSnf}RVucG zPzWdI48}*mF{_n1yh;X|7}_OTl>TU1fh8xA&Z@5UP||tjnpI?UlUhBg@CAQCvhj;? zCGssO;W*AII!)TS7?Sb5_|4_7rv6gxOIbI&rB$s+N~R*Wjr^6HTbhu>z%dO?HRYAX zNF9HNW5niHCJZ%!n5Ez07#o6_+1gC6M6FiS;guQVVZywkydpvxMx-o02!*g1p+p>^ zf<^;}K;9vE4l#v+TEr}d5{MChMfHlKTmV9O`{xi&=<1*{rmVe>gFF$*1o}D! z2f9auvCg66q6M?(&9az3Q{{OxRB8E+#iCg=tY^*iw6lh0f<2vBd@(g9I5jRbD)Ous z%iC7BHZE_hSyo>~UfEdF*;?PVta;m-j_$5i`?jt_dk5` z^B=$Y?)%Tb`uf>duRnYB&1Y;rfAQgqmmj_S{Npdad_p^oufKiq!w)b2_{T55`}Wzl zub=+$=P&;9&)@v?|W zi8Yf_NI^3JJ|Tg=08NBRJQHYCB+xMO811#L6ifu;A>JU$CdDy6?r@B!nDW%By4X{ zCkeq!Ue+QRtqdY03<4Ndy2iiStkNanGevA0(ItT}TCaqZMHzZ%Aq@vorvqXJ z+OcBgzl-DJ*QTc4y?*`1HG%}IWgNksOH-FYnej^#*Kgjqa)TuWu3x!nio%D-5O{$| z26j;wsY|E};6MOlaLl{6Zm}4o0F6>Gu`;Dz$jK1WfGh;(z5npxgU1i=KDhV6-P`o1 zMFcZ+2B9QoF|-F7O6Du@5zLPHg@teoswF(G_wCzdi zZC&V@EJKRkdkt#4?6UuFPMWPPQ{ zOA|M5y~_Zbm7N|JAFEL&3gwZAUX&On8j8`jzGfT)#Hbt-rWP^yCC4zzNkSeY+H-S` zF&vbBlVcR?=x8xKmE7u*40()rXbZ$}IMN-m#joc)nQxeWm~Pc9uGh-Jr5Zz->iUM# zikiaGDrhFZtUkY@DJ{P;CMh=xGrqL!!qPH@GL20&b@dYA7bOZzq2x2bNPS~#Q%ijv z;XdjGO;8Fj4;i$<)Fp`)gFmZMXd7647We>=CZGPoptBQgE-TNme6EyS zuF#RXF#TmYif&}Eg++Hokxw6fN9AF`WvpArxXj1#mAOK>RIZ#~7-y&sjJ42nwzmk@ z2+-(yV^d2V98*-1hhE9Y*VB;4U?sy$p!}3{qRu3tLb4LxgLh)>9-_o8Hny_JAEm7G zN1F+9?3UQuS!3mZCoLJrS{9T>WJ30LcjxsU51>$7e*>|ZHNC;h%*PS|ND!*dU-RAxl_TfY}rzVksY2Cl_}o7n_Ba*7N4u%$seyV2=I5S)Pv8 zzTS>uq27tf;dw>rrR9ZnHPsLu_ZABapE!JE@bu}4fq{3&N8h_R{Ly<;pWeUzs+fozI`$fBMk}kM7@maPKCOMep9eH8ODa zc5d6cp|fjMM`wHUs+Rgy&2_7r>(;h4Zd%d0W9_oNo7NoM(RFO^)|0(EP9NHJ z=5Y6!Bi*NucAq}7>*V2`#|~^ew0C3Aj?SH%mT&HCS+~4?Ra^D)=8BHS@^+QW+L|ib znk(8`tJ+#BJKC$3FRN+qs9e6RYFS6cisetl`|Jpu4t=R(^0i~ZR56e^}9AU_iStL z-qN;vOULovjs3^FkN0lfzJB?(waZ(o%ZoD8^3sU{7@`(Za73 zjSeM)V4JAEg!EN-%3qH~W>gSD=rbxRkwHB&j4*>K(c!64VPpa#r^Ux4L@H-^0uqXS z5_V30-p)Rrju_40&4m4qr?%ojPUGTYhvLaWDV_*1#4=lwf3b)uA{=CXP_nPLvWbDW z#A_cFC7Q_6s!G@eQy3Ob5^!P3B=7}CYjjCu!!ib%F)~0S*1qDnge?o2Afo!RE&(V5 zh+us}RuOxNKF1mbgo+s*hGy_oB9aPj$>+vKsbfb1@!+_mg39Pvc^n1Ja1V2je%tdZ%{~GfA?Khnq(zNDz|Rk zx_0dvSI!q)I*RNc?cInC#p9hvrUb%Gn>XmEPuU@|~HFfpUrOOvbMu%yKRD`-j zWyXb)F=Xc3A%a3c!r@G0ga~4!6ytGxS&_c%1Tipnetp*mNs-QMIHmq4D=tK96fjG;^5@?(4~u`7qN8iKZ~%69|{OW ze1%hYR(2+Lcw$llhU6r~e(~|~JRIt_*GUUw*wFUBu?k|ySOhDSwd2cb6Rzd z5JmJsB2587exGB+&KHPLjuCpXYfuJ`fp1I)hWZ2?ijMO<0!q6x9jWcjKr=>(MXgmNXOl$}MJ6F<0~%x(o75F;m?gmxN|Jzun)r31B9Os> zG=L7mKU8R^MM^4fXhzFXL|!7sD{Fw3Rm%L9D^wyDEuo>m@mZXN1jq24uq+vm3W*jz z1&-OmYH&K!pFY%gY*P;vJ&Cx5SetNIEGoZg$977_R^;122|D|2yya`Y+P(~&R`NatFj?r$>h*cy+nbsg#FASRl#5EhgU@N^>w zy1R#XDMMNnza)StEXomAoLQ(~BC1R)B2;)7WsDXPtm5G_6GldYGU%9;%Z|6Nm%FEj zv#Y0z8yV|VT!q7fg7Y#mEA#UkN=la1Rc+{K-qP8=X?;gmS9?$Irt>4mM|ms0a^c3i zSKqyP?cV*nPe1t>JC>;!wb(JTzvWP z@`pEvo_sL&^5K;ikEULJbmP+xZ#;R(Ks|YFY79~HiNpJPb|IWzy?$j|XGhb@mb#Tq zwX2$IJC`m_ww$_$3RTtKl=T;P@=V!&GCWpqw_yq?#`FdJ; zxXgEVp66gY)6Hp)qwNekD+`;&7PgBmmRPCMW|4)R&i0Ef9IPztEG?|&TiDFEu(h;s zw4UK)W8t!7hO>=@o9%25`?;PD^MX7UMf=;v2H7QsI>!b(MFrT$hk0Ztg%)MR<)_3{ z=4ULeDFtP!O7b&O;_=6ZPzlkCtPDU&N=Sfas4!qkCZsP+qgE@>-ty=KdBqeO4fgX- ziI2gzi`5>0m<&9;G{oR;mK+zI5*vkJhUm!=0eEG*VD04NX7A-AdFgo7&0J221-mNen|w385@->ap5G84DAvbkBam` zkRyjfHgF7-BltoIxPUd3WH?5EMw!B(>A83j&d>mJf!UN0y_5)AU>7*%=+UE~%;Cd_ z_wV0Ng+{Q3#zTh=_3A{0c6tiUAiQB#hG1k9+>tYLT4+N-5^~7#(XsL23l~Sp!#FvO z58iz5+STiqCN7N)kByKoQk}XyK5=0LUDSoKq0wRS?iMQ?C`7qO4Gk$h7qTCWjx|>) zBb^bBAH{fw>sJZ&*T~Sw=pcD;7(GrOs{yd25r=SjRJcwqo;u%1zATM^1x!{`Q&U}C z&C77-nzcYo*M^O(cg@1rWGXNRmSubP?k1!!;u*Y_R;^iszsj`Urf7>1@UjgL&B9PB@fg$%zKSIQSbb(NHq1g<0|;(o0X5Myu* zC__R*1ITL=VC9=Fk!Gl9j(Ov+B$_2S24ReF3@9TsgAnC+I7Z|vyhHHN3CE~X`)r$b z;hSwh43)PyM&?>$qGi)0hd>R|u4FUJ-{1unFes4niz{-As0~!5XsG5 zfn%TnI0lFzYoLL%kW{LRF;2pHB*{nP;DC00-##*95OPsgl{;|g5Q1X$q@FvAI2tzu1|b?LDTuet z2l0vgl1Psbi7Jkn4zh?BS8+_FifsVLDE~m@tJ*ISH51b$%PsSs?djs`vpZAIKe+Vry$fHyf8p7+^S1|kubtUBb$aXN(_6=nZaA{FrF(V7mbRjf zisZV2*wW1Kg7omrl;EtCh_s}z%+#pdjJVSLwCduVhVp{e>e7z7ij_?@2xB&{T)Jz+ z$^+Xsoaoth_Q;;$QwPS+9+?<8J~?!PJTY|Q!r-y7^GAmI51c)*_vFFt2X}ASvt{Mh zwM*A8Z&=-0y{xgkt**4Sy11dDpr$0JEI+LvD$*`N8oXiN0%8!>n^)9Go+WfKDqyrUpF^`H;5_Ta8 z%^30+;TS|R!ZDtHzTN@;1!bi`46hAv3SWDJhs@gxo}<> zb!diC)`^5;kfxB8Bt~a|1{?uCU=ct>N<=A22BTqx4$5E!IgJidhsFZE4|cw&maxec z_hvD?rA~z`+7mGZMgW8K1-w82Lt;V&Vo1~(CrD5W%TFSV0a~aqN>FD!VdO#EA_Eb- z-~bW8fD}-I$YVI1ikuTQ6Tn2-f3|M`4=2oNP^%2GFy`qqeJ95+j9i=?#T%Jbpvm;X zc0^WE1SvQVkU^r(^{~muk+=-52gYI-?KoDQJaOvS(c?#tC^3>sM-P*a9y@g8=)prr z_V*s>Ie6#*LnwPVietGv4n&5;88|JCY_gX#=j7x_$Yus-lYo4~#trMc;FyhFoA~a; z_C+28$6)zOUfsDInKbek+>YRwqT(!~`Yvs$+PZNC!kG1ITKiA+!ZA}9hmglijtyTS z+zuwxeSHuNv{98<(Va74F~98zI6LXIfhA5&%CQnP7QizF{mK7QkpOl`#qDz%^jTJSuygPGdM#Hs#y#H6^|IvU-ANlXhVO!49T; zDw2%4I(AwfBibcqU&ReN3B-u?iE$w3WT%{&Qn-QJ6kLE61R5x5VUv;rrOthUM zeJEiGn{*J>4~^29MxGG%D#^#DP3$FZ(%N;MYuByb(6tsIpzPYX0l#Q|Nxq|;T+YlP zBp8A-a5wW5F=UXaz$=tIU_4zUo;My~o9!-{KgtwPbn#Q%DBK5V`|=LAAs>#wt$}4EwqrxzxP_8cF2vo63LmV1H99iWT7#}z? zbf&lOSog90TlVi*yK}>`O?XMP)vai*>ZmVYT2sO~Yf5sNHk{#dC~k? zPIgwr;K@i$D9B4A(w(!b3igAq83T6~W4|83k-NzF3Cb`igD)iBO{EW{L)hhvsAoJ|-eGJxK-2NlS`VIUy2`!Dxmxw?P?ScPAi*EUG0Gl&oyPYE5K> zF04U`@iAUyifJ^*P|}W@5)gy(k;I*&LdW>|!7)zmZuzAp%RAR}ZQBaR05OzELn%QS zq%xEe$rlBah-V-eXa;GG5Dc3j4#F5=8njEY_O(31*toznzztd1yRb&1Mj0U(N{nNO zgGYrD;=yj03XMPv#;QOJS-hGd8!Au>_=0wZEDq9Ojk2K`Hi<5nM?nxu=2RMi5vVnm`*UZVEyRf`R=Ns=K;O2|gWE@L!fcmWY;Cjc(7QgAcg-@9*bPj}D0 z-B_7W={>lY5(x)+-~JvtkiiZvL(a)?$Dl`@!H_!bd;}F~QG?^*qlXS2KG4gl570-Y zBM^+@81mtxoNfQH<3~A!JzS3*$cW0J43CtYlXmF<#}Mk135zL%A(8PJf?+~IFoSr8 zug_N_CLSSu_xJAQEAZA=QdWSs5n*6*bJKJ4QcH`nF!epqvjx=>E=vdZZM`sjW^(N8 z`0zPIG83ai!{^UoJS4&xetbT+xVShwJDUeVG)j~tZhjE|7fJas=@5CMT2e|S6;Vb} z%yd%GCBl_IrpRNkYmux#WZGHDydoTfs77_u%MM^oC{EWXm6U{rB@5)hX?aXwh_|%- zwq8kQccbKYqz({B!Y8Ssx}m7FHoKq_Q{Rld%JjVQxb*D6sMyGaKaUg zK?XhBs6r?N9S;yA90SBCjg#J_9kB_S3W$TWroOR}lDd&iJ++9%;20`uI@78pLs&9> zrKbOBr$#qA(-TpO@ztav9Ah*x!JE?tb!m}C-~$AqMIEIKVpL#$EsP#hDTa?6 z;pyd6JV^WwTshwzCqv2RA{q2zaF~&FtQwX=K(|zrlbgv}MXay%`y69sVXJuVCW(2l_BADbHJ32S6_fzyyY21eprU zO|!Z(ODkg&irWjZ@Oh2UnRP&58MUAiW~3}Sh;fFiqXV(?v9QU_OktJU<*jwsFOPio z`2A0AUzr*@cHz{%a|bpb-mzkLS4-FG>gKx4minx?aF;MYTQBE%&i3y(*vv%vg672$ zMa(P&!vqySH z&m5i@I03|5yKwgU#dFsu&Rx5BcIrak<%etdkuv(o^EI)00vYW0GUTK$+BdVi^Y`2MY3W#p4XMrHMqJUJp^AI z>{S*kE^bIT2ALw}z2J*L406N&>(DG(ZWZvYwd^1_O40BfNX?fK$r5 z3Uv&Ji5$Z&T(8Me7xyLlNTv}hU>YeoRy><%WG_!W6S>Ud3<3-V&;|pGKn%#j07c^c zip1yyuP|5%zEIM^*rd+X&ZZ>ljFyZiayXkLPQplt32y1I#1B$bRHQhjeJP_i69HGw6u>0KbintLUqG&wm6G@tyrvQkG$}a| zy;4CzR(1|+6l8R?)gJEMjxeTkRl}a0>qpL?fMYI>4hYAL52Gk^Gz?8qoG14J~=#+$@ zG%Yxw;_Lx2WNrETCghAjk1Bu1&exdHr6O~-Oddc0e%PQ)Sw%x$K~+vcb!I_jdVU!z zM~22Fg~TQ#W@HyuR9839g^o%Vq7KoXN}!Ce2zn(l9D|^SU9iiqIi`+ZRCA0RV&D!Z zF%n!tQk0|}LVzf{(ZfLXZh z5CD=904jB+PTYUY&KwBDhy;aA8rjLi#)HA_%gxF|$ZblgpWj_Pw>*BdP|8d%3{J_D z#si7@It0U%&+V>m`jyH_kJDlq&C-ed$U;|ifPS>CyLzxmoRcRX+JG=PGtZPfMG7d8 zqoRb?6;T86`T*7-J3*R43*t~o9FCreHx$Jvr%oz}K`708)p-oaR6@p!)KqAOGtdnZ z;ymntVBi>thtHA3NCC_#hA~4Kep`etrZo_BggySs@;8NJxP_Wq8t@p*&dKgUC?gd(M&vX&k(eBjG{mqLpoD@Ygj^6YpKLqxocH>Yi({ud`(4eZfZnKuxpsN zZJ>*#uk9RfyIJm-kJ!(`M#RN-R)EXm04Gat`}w{uiF?*KNoY_uu=GxDmV>@f6m4$`%42vc2%vdt>9ZL&~MKfkt&zZes-aPw7i`?w2 z1HGJMg1yq?LJQMkD>cWo)s!r6tXSLDuw`}oZY*PVZ9a9Nd*DRxSpU(HU32yN~VL+Ph=@uCA4vSGTR}XzFZhSkqd+w!LY? z@}*lkSM1xm@#yZI=Z_p7J$>S0f8W&b!0pM&TNg&}T$;FhdGg-m#DmM19!*`jePR6l z@ewMIuTDLhx_bZ8<@=LY9$mTi@bXnEkEgERnYeuW(&f8XrfyA4T)%MP>V*rJM@KJ> zUKlz#cx=zH{X2RO@5RaZ7}GeOsyt$dCacOy0Y|Ha3+$~IVRDO>(A(1kJ1MIr*2!rp zL;|g>u15SqICRWu9i5%IJ-9KT2jt|uS*E9^cC;;hbob7G`j@}_%g;ZI^&iKRD?2_i z%*&;|G>`CrDGAXSNI|-UkO>L!PEU-=NsCWS2xol>R+dmG-T1&!{-<)Hr8|raT5<6dz1$@EOj11677L);EWG@vwu7L^Y z1jQ3F8zC4fhRlWv;u&Ebgg1Z=90PptPy-*-p%yZ{LezZp$dsIx5=cUu%;$0$Y@%hB z&xNS?bT;K0=s<;C$}oA)ZdB5YLL`Ped5NOJKqsT0jC%qi^kHnIMZiV6$y`pIih2pt zYHq1WBS&#KbxKA>65?K7`DFS>=)&}m*AF5YOl5%>UEfPP1S1dwh-kV{q{0vloX9vS zb80!p_fo4dw2+VO3b}{BN5+WKwuf+Jq0M3xe zl`}Rn8F4eqFUGHd=!jVW+hN9bOnn(A(=*bNQ<4huvxy~BRFHvQsi(WEi#Si~T6=po zV(L3JF?jXz=)~9{C^I&Eenbc2!FULo!DgAE6$$}mgk#Vvp=knDXcPaOmM(%$&LR!RfmKzbyAV~+>*(-Om+`#}1 zx4S&CwD25q5)!v80vJ9>M?>1q`vfNI=wBch5K0MJ+Et)rPRqkA@)%?=BDSF?(8GPt zlPM}#9z{L{mViZQ;rSs^fm9$25xvNJ6$2Tv7WMLU2Gwz&da3H`qni@3XeF@_4=rL1 zhlmoLDx46o=WdtS6lOc?l4Yd2V1XFGd*Scqir z?M75qH$P7|KW}$GZ#Tk$Fh8-d4x#ADgb6{3V9G2Zge62Yp?Jd~7)m^H!-Io}Xa}s| zjLr4n&Fk&s1;OxE!7B?-J8LO3buo#iB*)iOmbNt3)Yq0KB}62~hsH+-I4zm$fQ5(U zOuGdZ_6uj&FPLdP*J9CJ3(Gl5Z{jp}mivOauJhh;Uo_XldV!nu0v|`KKw{t8Tl%{@ z1h_l9*)MUnwd1=u*w_;CpNRZEu3jNN!O_7{5dq;bA<^maX=VAvgpH|U!TIviw%YRc z+OlQ!Wh)yiRy9?svZboCt+s202xB%J>)FwNq-W^Vp|P{aCI(Ml8aWNhOpU30WfX`x zH8FJj!obndvxkSy95{D;@2P`35AWH$cgx!C>y~$|XkFLQOa@}McCP5zy5VH+?(x3k z*GJC1KQa95_Pbwyc<<-uPyYJq#sBin%Rhhd?2j)#`KQmH{_|JQ$p7;C#ee+iYc~Js zC>mrKYjM{`DZVlJ;g^OJ1yDQ!M28INHC?)oc zROn2`03R6$nb#GDGfM2<7}U@vllfdS5?OY!DZY+;7A>?>5kEw(jXIaXHP9}d=|j8t z3NS-+4u&{JLXtk;b}EdGBr3dj8Gyp{&5)>Oaa{poNamZemywf3j+K&+pw56y$pENCGApBqcFa8oXlQi|mqiI!Kbe)D_tr<=-KLW)R7!#v@AnEXZQ6 zRALxpmk4IK0OA9wIEQVm4DXDD$l94-80Q(-`O)|__+DH#Ix;Mm>4V&zoSl<}up~Dp z1CBv?%DudO^D5T6-rUu`e{Wac$^BO@4&1zPabo=Z<%yy3k@KU7WX47~12A;w?rmlh zzy)~>T2v*ENsN!j{9Q?3By5bSA|YgAP%UXwU*)x={goKprn7RlhGUd%Z-hTtj9S2y zUs$(HYlw_S1U4#bUHlsp86HB>E9rG2-|RKD2mC{NCFXeMNahkOc9psBQet{^G&CrY zOnzZCD3g{~nv_$VkewfzkmAL9vGK`7lfeNSAqxC~0tUU5&Rxc<}gkJhxOtY=dwG zMuASi7Ztlo8{R`OpbWAZj*^qBW3|W!q(Q98hpNZ^;K6-+_ws%D3I-qP2VyN&< zxdDW9k=d~{0UU!~DK9@8K?l$v@izWJj=^3=#e=cMHi3X54$N(=N~o3|^j3=}W68?` zI>ezT{5&y22o^$4i40Xr1f7#(BhV(mF|iS>K^+o9WNzj>EbQ?|3Q!jVTJZz|F$hR` z_>uZDG$18q(xOj!X-QLkb#_KFFY!yP=earC_xk9XHTEUV}yMD(zS=TAAI%Mi>Hqt-@&P94~N?l=xgN8p$X=TBT5JUKCRYI0a*W#>C^eEj?oAZDch z5bjF@C-?Uq*?nx^w*5Oc?Ce^#X;s_$Wi5(hRc@4HX#{P^_Y&!2tt zhfhEJ!;{B<`t+l}e*Ww)Uq1WO=b!wn^N(LX`O~*Ae*W&ocVB<{$M3)T(|6zf@YUDf zef`yUuOOPwzj^h=t5+{yzI^)q>n}fh`r+nvt7^-Oa?_IWFJt8?0?DA+SztMbQJAOr z^qCWrgvh^!U+x6MI##VH305s{tE(<=Z>b*}I{Ux>=fC}@fBmPIPwwBpdFjqoe8Jv( z`RIc^o7S8=zVB~;`SH(xdj0s}tw#^u`||TA1Y{{M$%&5z9)06t{ZkXe(vrfH<3bV4 zgoSto1!$D^R;|QnjsOa< z5y50t9o;v}`VjE}TfNn*iI_l1Bbf?gu2d)i6m?GBfp(!NN);Pw%^G1WhEyRQzyz96 zBdi7ss*)IKNsNs$e8~tbCGCu#lx$KVF?dqSAS{~ zNvex(p-x5KCn-5qPEHO+qD;Gt`3!@yx;0aPdcoVUfp5eY;T@GPg8LQ5ri_hD4L~#` zk&~T{xmR{(Voi17<_*jC?cRtyX8V>ECywl%80)+B?!?sPVL0Z}#Lz`tvNXg%GdJG7 zjl&Aqf-jbs5Jj#Ylf`pP&;U4+(BfkZTuIIBPmb)ZB_Fh%On z34e9bQ)nTGQtmKK3bhz29w8VWC+1PP`{hQF5(**7)57yZBPI7brD%D?m7fkgD%_6T z-1Mi;9WNDn8jp}XPCTpJ^xVfJc5zNQA$z$(zAk?bbVE?%_HF6~1&%@d0G?yFt0h3| zQRt!*#R~~eSNHdZbwW{`M=pSefwPf#Y~*31ol7!L5QscNbYL$R4{87$WQYW0K~2webuK-TLJUw zoP^(pi)_VSr}lP_oj7>$%;C%Dk4~IFJb0>S?EIli7th?dK63ND z$=mmD+$Y{vd$z7W+Oy-#k$nRv4-NMraXCgFJBNeP zvGMcZ3-zNTXAg@5Ho_S4z^UH;V?8Gh>^!h*XZbV=L05YI757auOPH zQ&rANY061!Da>js$!RUgZmY~)T9MOOk=<5T(o|DeQJhs*S0zHU|PmQAZRZ$bjU zV)NG3yZ3H7dVFtx{~pOYm+T_Sze*X49{Pm~rzk2rYz00?+jlcZp_IJ-8zy9>$rJ+;TF7|)> z6za>5%l3sD8msQ*yP#d!K9>} zF_wyvE+w5wRCqZAK^XKXr6P5CEo1=X*(XsUfg_acqL0x{_EIubGSZTy z!q6d`lpH806riESe6RT-YFH%oD*cgg3@D>E%@X4hqavfU44(f;NoNv68A*-oGS-1B z(?G+xCw-{MJER&4k1DufB$VNilFx!C_>(f?fijHkyto1x42BGei2u1}HhF(Oe&QJ3 zRlLqI5@O_lRSmL}?5s36CO12|tTcONM;#)W4QpF=Y+ZT$aQEbR|GU>OT)8wfdGS24 zeU%sd1j3j>N+RpvqE%Q_5EmbtmYxc@P!VuRNQ`9(NlGKfCq^q_Ok5~ACO%A}`bOwg zmQ)!PB3V3@4A*OHUr-+XP8L0p(1`&trb-YF6Ka8a9U6A_Nv;}qKf+b^17^&>ZH7qxU7Pxq|C^~jQC`fOJ#IZ zcfVN{ltIm;8$p~7G2EnNmxdeFA{E$$$AthUWW9XhDoUPhGPJl^&6CI24Lsr2C76x!g=^au9L(?$`iiQNy6uHcKHjM6b_NgMZoV%gQolbjC4B}Lr*9-exUBM%Sr z_ga)ncGJt*U>##{3=reE#MZ^$&I5Ilqaz%HAGLC&R!bMLh_QEckUs{eC|cuG`oLPQ{o8KG%H0~G-D5IZC>AvrOTnFfO48N=ZPdp8uzWTdrt#N_7Y zLNh#j%ulR^P1rsM8*7{S^Bt`h5tD|qan9`InDYFL`tpJmOB;K3Y{jZ{Vsz~82X~%) z@|4h_Up#&Km+xMG^X%jAKKo1?a{^H}WUp)Hk@vVC|MyJM344vpc zv}5(&jqTglG_7r~UbD2iv%Pl1iso(WR_xop@%aAk{$ss^r;iNx9UJaHI^0JEE7v0< zIuG|98iZX=?>~QP{{Z=PFO~k|Jtq(DI?%mo*QV7QS1nz=v<|D`ma5{q(!7ei^n$eb zjHs}LV4o;oSAR!q&n5HSt!6tdnCW6U!*#KRv!#X8LJRwOs^TzTRhG=Lu$gV)FxSFq zzJ=2q3rFgBFfE+vu)uaG9w6U7C*m9=z;#mvkSS+%%ShUb$;X(^bD~rW8 zGi~f*F)vy)%hqlo0&S(s5Ah?2 zMs8MWYg6sUb*m2S*>>ad*oSv-eEY?dyEiUg9>L7{+|9|sPaod8Gc|g7`1J6ZUV`Xc z8asXO_NA9E9{l|CSO4|D{OkYw-~YG&{@?!NlgA$%JJ=1))K?W^E<+R+zATbJL`39>+#4iNhQ#Ju9OL7oOnte_3F(_xP*7Z2Dky_-4>UuN zUtt>LG`LELB_f7~LN-crqh;ijjG{95Qvqva%;%w_LXx*Z1|oSOly(|rfTfgO2EhCq^<^BodjPPMc+!anvEpMefiLG{DHi1?qWhY|-U?0ic~ixJ7N3#>&Ql%1K8nURv8lU|sY z#-j8X0dL#15_!y_{oBTdPF}q-A{p1Q$w?yi4B>W8W_1FjGUXLzunT%s5gtP`Z`dUv zM%9yI$ni;$;ETaAh-4JX$U;k0$T7hY(LsNYWB#s{%x|tsK>Qe;5Won>sJBF35QC>V z#<+2*a9hhA%>7DYw%~SG;LSdr0CMhqOcls0R(391+1c8$s=T%dj>)U2PcN!UEvO)t zOhiI@SX6vkW^QA1i(2H0pt1TMmwTP_adLI9ukGBhPN{MP*v+Ye=Y-BY48RA8XMnww z)VZgrka#Lcq66Y~r=295JRa0V`a+$XTXs=$2%ULI72bMn+NGU1Pq%^;7#GZ_mnRHuq&P=v2n zCCBn4%Qxl9d2GN4O0JVD-xWmfuQ#2O>bARO0F6e0-367A4&%`6^rkKN`OeUzu-5Mcs3&RxzXkC}13kn}lD9 zds6YVmKw^h$G7A6;cK$VBhAyxfu*ITaDz84&DzDo-QArDfN6lqK!h=34YS0`hKz7V z)Jd!Z0L1vYxj`)mU?Ky2sYC_(#f1g|F{#7|2?-%Hl02CNeKRCO0uUF32Y; zz!NW(^th<%(t_%;VmC*-!rYvaqQdOVOl;zy7Df}Kpr93IcVvbG%IcabMh7$qtY(0H z45q$|<`C&*er&MM=GE;_?%(|Q?)3+^E-i?U-f6N2JGJ%YWKg!$M-6DcmpDK^+SDcmDBIiw^j zrn)e-p)#+%p=@nO<5oCk$EM@GyZetH95{V+sPEX|nWKYe4iB7$T~Hw%CJ&xDhyVsR zrL)KPo;}fX?!-QF-?6<)9@C9HW)&++u4=7quPeg`s=hQAjw#Ma%#06D2=xnNRcn_e z0q%A|=+PV(+FQ*e6Fi1cc-D(7ob2Z~+Rb)$nCoOWf61a*)(dA++F8!FTQtkXc7czZ z4eieM3*22<_tDzfX|bczVnAfk;#p1(mN+cAI4yQ?Sg^!yo|VmPvc2QNB}?Ym+0Lik z-gZ8=DcA~?7H99?wW+qQG$7D}W9=Ol;gyD~d}L%WIW0L3&!e2o#M<(LZ5vi>UbA#X zb7gBy5mEkz`wpBryz^+!roEe1Z0T${vUg+uiM{7e_l%DmpPD-V&8tuTzyIey|6l*@ zZ~x=}L5vj71=?7NO-jkT zpu9sO`R0XymqsHqV#^Dp8vONe&G0W%gMbSUChe56$zv!LN@yQ|Iu|As#1P$>FvlX=fnzeWGGx?3uVmsF*d;MqAm$Cn#D|DH#^4yW zK*2P}fHJ?sF^0wNFT^u{pJN!_g=2U{fF1aIyxBc zO?4lm+aVkrLdVr>RKy7h$Rn0zVr$~Cv*%s zq}|g#7^i8wJag)%vm?nDZOKxC$I(}1LXOCu(xmDBR{#w`tw)#f^?GBD7No!f!l%;Sog zy}lqB5QD>hwdA{JCACEDaXU)m$$57ko~M<1pb+Vk914O_z(s>Ha%%-RG#sOpF*5-i zqeB@n^~HdOYywIZUe(@2ZAefloKoAUW<`ZKgt!8tY$&?-&OPpqmW`%HJdUBC9 zDKo*Cm1rurWv*y%Ikb1j>vvx~uzN>+Rb^FKX`wBjC4zJ_x?EsT0Cv9UY5BxqPLS5V zc5;GGC5&VE{$?dG=qEbZw;&?{)7oQuH-CNq_4{wX`0-n}-hci2yRTh)H4*kXO8dRJ2m;#)^&T=4sYsTI=ZB8Ra0?SUEZ>~yhRo1P35WO z`El07AhXFmGGt+Z*JC~&vvGZ^{NXw}__E^3c~-FJ6MinUJr~Xi^_G+ooHvJ}Vq(J3y*D*inPS5{JQsR-J4Ho>q^5#F<5^>$oDgeGO(@7tMU~RK zv}J0dzi(-CXLH$5PwU=o<9qNA(A&}9+0a~-x3smQXL&>4%I1|_b<3C6@7y`@;VQZ+CrJaYsWf4)nzODkeNEDl9Y{Zvp;+2LE6M zWwa?#5R49JU;yPbW@+0ra+)^;j=>ZZ;#)}I3tvRQ7h+*Fb&T4) zUj%j_00qh*E)W7Dz3Kk;8OWn&hJg?xBB%i7*c+bRsinbsPgPDTpbZblD{m z4B7Q4i8v)Dv*ec)av}qNjA7If>5@UtiddGfJ7hHsXGLgNR#x&+$215yMwBru6hbA# zArcSm5doD9^GYz8SsAU1T97bYlADuPXtU*HWoD(ZQBrJMW7XmP+wdX-j$vx)(1EEl zr=B`{=J2^^kDNPu?3t5?PM$svj=?7E^qEtjA{5>r7;p?7LEP$tbft%*@k#%fXe zm{e23PvRImDDyuG#{gECRMPBYfH5Wx6^_w-RPwFpKy##}GIHq37)c>f+9=aAXj5px zv}jDCm6a*eokPP^ZBPHeir#^?&gIoWnX1NY+{u(TSZ$R_83l>yxiN8x`GuuDy~<2X zwPn;Q%A$U-yRTm@0bhyoEVM?b`caJ!y7!qm>?K% zwP(+sWo10=Rr2T^iE)wcAtdF{muSk;-0d4Bh0wC4rNYqu7_(`Pl9SuX;L5f1Pl}@V zQklpODvfHS4%y&wGjrXLp$b<+?N|6cPN$xbvV$b5HVnp!c|e414;#9 zU^Jc-hzt<7-mgsw0ahdkrcu0xX;9Ko1DY}ZR*YaMffwPXyeSOt#bfZbN8{m5sUqqS zQNjxngH({SVw}h~BXjfAJLY*}O9Y zrnnSitT`eg%HKCBDk48MvC@`_UZJ))mz@`n?cee9uO9rnUw!xc-~Q_Ag|kcATiEo` z5Tu-&VL*!WnADVnp6=z$&anwDyWSo;u*a60xp3a&KAx_4)ng458!GfJYdo}T?K>}D z`}oc0UcPzq=H)FmR_^I$z`sCkIQ4?-!{-=eh9`N9_kWh4(#h{^7k+qJR$?!VhoGCpCOJIR&twdaH%BC59-AB!mk?=T#d3<7fbU)4 zMM|hf0^t7<_ z^vL-5fF$WM;gFDNJ6BpE{CQ6 z(#>@c10%45UJpq+Jza#h9LgyKf)Ix=NEL~Zcn~52f+11QK#Kk?3L}@32cA=UPWwDa z6@e!907X!U9_zS7h73I?>3<2wNKP^!4+X~{hLO4=eo2R+e1;75yDVSIkc$N*F)Nu- z&*1M4a{@kP39J?0xoaCAw7BtQ6hI}<&zhH;k5(9k46dbd%h_06vU&X|Q%h_WIWe~4 zz}^kunDb|k0%b0oKXK~xk>gJve)il+0wyxdF@ckqR6@Z6n!%n|lreyqpTIFPuap!w zvo8S_zN}Z$?0hwq3??$NY6*WZYVDG?NsH#LH)6&PCY(do9}!E+v~I>;DMMr1R097rrXPoIV=16nYuug-#;?iKRg1I zSv5E^I5yGMJ5<%&R!~u2T+^CcTAxu+nVwr3ZZxN4WaAr7D`gNw&2qkhkx{HSS@p+a zKRh_WP%NwafGjvdASNA1LaY|)4G)1eSSU!$f!dt{)6@g8T96H405EDGyk$ON%@}@{eB_-S2`P8E}M3&Kt zcv-5K%AqQN#Rx@yaq1MDh{_1R6!`2yj!-|;i7H=1kh}uFAcw@Ha2BE(MbaUFD3ki( zj+pTx`cb(f_qDO$he;)%j6Gp5L%^FzXiy*^hCPriF_G+)glAqh$H7%A&gWC(>5fHBjKO%AWpPt$LoJT)){e1gq+!M4 z>W+pYTSiQh$uBiNFwx{^408(&Vv6KRHx~z2HWKoi>+U|w)9tZfKWALu275Z<;@0!Y zS)TJAcbS6)$zv>QVzg$KYT=V}oSvNH$hO!H4$hCw;*_iALdNUKIezn=2w3=p_meE= zp6%!Iq_5jtgP%)8n0IPQbZ%~9Ns+atGQYW@ggqTsE^QfHwRCc{Z}a-`om8M}1sHS^SP5+Ym;jWf7eVv;}SM6Lgw0r&d{;4%b_ps3czGrq`VBaVfawA*M9Ye?- zJGT4Ck)0s$lg}Kyc>bAF&m1~-c+b| zfbzt?UC$ofkJatd2e$3ox@OPj$phOq?44S_d3e`z`#U*|LTE(@}j~8PdTpih+z{PE$ub&s@DhPfS!&}Uzv}B8#TCyhRXC{~Cr+2m0uI^j9c6j-gb$utE z+I05#u4`uxzjX8LJ1<|qdHMK`Eki4oRu>l~STiC^OOi6vBCLsFQ9-V3?Nn8m+11f- z{rt(VAH4T}{-;0xr+@gvAAj@nw_bW-`-aucwPmd52ZXW6p9S7DUD~Z|8Y=Kba16i( zbj}%jeGE7TYe&qj(8n;ZgrgDA46%-8z%d|uz8Qq*nDkKOmFk$9VVN-S^hXGB0f`<| z9|9O1=&C{jS!65#v&g{lBk(eFKps#F5|!8<$1s|x0Y&qe#aRI~B3J3ch(t&jNtBpG z7}5oKJcMIN6e*2NKy*Nwc=&-Ad5heDBm*(Lo-T(vjv-wqDHE|n9^#)Qq$r{Z5_Cc= zhnjp<0`?)2oD?NFC7WErPz6JZ;23I{9|9bMajIyYG2jKqboXE`(}UwaK+MKX>)2F* zE$8sz%PK`>OtWG|X-QcoOA4~_DV>O0PORDoS9P-VT0xodmAkf2Jab~-l}pdi(ZDfh z&z%6lT)6b?+4H9~Q{QJ-PmE*aYb(e{$AfLJ3NxCRpO{y|&KDe$WTxYY3mFZ{OrseL ze*Y4V(SeJR?dNbAYEq{b(u zR@Bz9gijn242+HT4UhB;t8!o{p=WSlB^wHYV@8HKBv!7q*?^v%cSnXv2fhqXtmbk_ zCs93(<~WW)k)FU%4MPlQu-^cE?H`;tOT522-!4jAH;oaG?}L(qZ+#{eS$ z3IG~TtzWl6&GcxVS~O+M6iAXComg1GzCvvE45Ri+Y-zyG3rkoq1dEXOM6$P)yFeFlS zkTBF91!_+*3GCyJY%dUq%ttxzuW*d7Fa9{xo=OlVGQZlP#Gch^6XQg4QhXdk8C&Uu8GWa$>(hW?kI6sc(7-DxUSRLoM;&I>UamNL-T%Dd^ zGR50tA#)`GelD)gk4J|41^T)9d$D5NZQh*6pLp!?`STp-&vlyjq~qKt7UIg*%h|(g zo~tP^EYc?+HYhkLG$J`XA|*T|Eh;1{Hli@yT%MO&UYJ%!dP*G&v<*)Rc=*|UAqzMTrqXgCH0v*Xyo9iW-R`?nn2vuWRs zb-TAt?wA_ix?yC~WdGXH?(x2*gDcurEotm-uj^^6?OWV1zH-sVp=Ad)4ximWb>r#1 zFJC(T-mUYWy>a7D<8al{rxwufBM0TKl|+U z&p*8T>ASZ+fB!b&>yKah_TzhmpM7-a`%hl^{{G9~ym$NCcV7J2yLW&7;Va*LeDAvl zFMsply)WLq^Z8r%K6&j9E^6+-eE0rK_ujvA_rdFLJb3fXZ5!622w{r}Rtb4{y0V3q ztEUT2gjhZl6KfP*I$D{$?DS$=c3wtOVRmwPep+>5#?qGZ&epOeZKccGE64gf4)0!n z0Q;hw4=PH6t$DNwlIA~M-A39U*CW0AOG;H|NQ6Q z|MAz~e)8@sAHH?(<9A*@a$tLXZE;*|Xh@K6M1%q7!WjCpVTD-x0%8Qm5I>4zSn`Ic zqs?Z+K86Vhpp2jy!7+dsQ2^5`MNH8<05Qk};0)aKswH3ziF8;#y;wh?F=|y3h6Gx` zj8Pj6R3wrO(Wf&rxaHyh3>-*QkP5LvE;ITVohKc6NCrd!;*?&Dh!%oJo~R2< zB{Y9bNO%MVGT|pl#0966;Fy6j!q^{DB$7lGymq|`8X>M9%K7Lm5ZZ_)2+0NsugCgX zEr;^+YfpMM7)q9y3`k~pYK8$tz$N}m2{>*LeGI#`FiV8*K6LZ!4+V}XDJ^7Hn^j9F z0~#BeuxVjlDKj-CJ=t7SX6stggnbOFubEfcwt4jEk?mKnJguP2d8U(|zI63ja14Rj zCAR*?<^~XhN+ts|l!1r-RB((!Fjk9h9HZ=GWW7>Soa`CNoEK!)NpmC;n^{S7#stjQ9wuA zJcvi)XJ$BrU?3gGD20heG(~B4oT5LFhpXr(bRkd+iCin)i5?{k>AX0Qg}zJ-(eoLe zkpjpC4pmhQD-&HRO|HUz1!N#Cn3x-J3+_*IWU!}2lENWRLVwd4=_j0`K$XOaR0XKr=GCggyo+gV=&V4}xRxT7@Eu z6;C{;Of3Ouq^nRqkH?<`S(z6O|WF7B(vKQ-qP4Hpsd(7 z*t_b~iQ^AGdhd6?{^j@Ie2#~bfBMsJKYa70^CzBq^Uiahy!ZO2@4xZ(tGC~N_3npn zzxMVUcUczn^ojkOH;u1fix1f)i(0B0>&jZ2D~Z{*EiNi}-eV59sK=2Bp{m4&gV(TN zpCn6kgn{L^&aAthH`~E^?&AxdcpSCO{Kw}I&wXsR9?zNW@Z{qT^I6E_JfCm)1T$Kr z_*83lUSU~rSzTQt+j=Y?>R-Ki{q}v^4qSTX{GCfTZk@mQ`ik5$K8ur zYhAUhxw5OdqGwUnU}wXcRqeZ0cOTz2e*VCwYsa>~czXA%7oU3d(xI0w?!S9s{|je! zT{=E>?c~cP<@z{_MV+&+dKh%%01~x869l>&3Hs-hA%( zYgZ0^c>DBMuV4P`rHh~6yYR)mOP}1i@ZsHaAH8zv!K+t4d-Eo+=2xG*^~;an`ToOq z{^tINfBX3-zyH}cU%mhCxf4g1wzsmIRc=-~lYk2r&UJHl2FG~&`LMmUTA-1flxa;b z$jd6u&*3-9NHirGLu^({bx~$jskOc;r@1CCK8pRJoFW5VFr99y&Yc`vdh3Og?B#jo z@}XDnoc;9u+uwcq+ONNU|6l(8`+xoqzxe*^_dZ}>&lfM=yLtA`jWbuz9{%j3S0At` z`RPL~P32)B3db<3g`Es$>P#(Z7)C{4aS%D!hW4!6exZzsjEocP(Td&7)-<- z!ZCc$K!RrIm5Q+Hok2731P~0^Mb>b@gJ6I!#F8jDhH(L*hirTpv;5RC*+42tHj%Ul zReKT;!znUol3U>zINrLcMT8=AI7B|s@ux8doVK|V;sVKlOn^j02ru%V6c{~4 z4(($k^ABa(;TY1TgufCa9ueI_y42zjUJiv(Pqk??K@#OEIc1-sr&9uzfPR6I2%@f7 zlnPb=$DoV{$A|-B^f7n}<~z2cvb3zcxW1u|ZE*OsPGxmuPEJmSm0j7(i}O1d)$iK6 z792A=v=kh3o`V(FKR<24duvkCs|;qa16r? zM9Y(y1}BYAS{oyf@*X=jGB7;Y$0j~wqXXk3fV!cHF?iqwJ5sQzPw(*Ru7Q!-)=s?0 zJ15)W?UTJisZ)_BJ)X&7z>TwRy z_i#w!Aj%kU3>uo%<0{XPGO6L&1itV~%P=Or0{kvSyN97^au$+aB(Q^P( z!_ig*!_jmYjEQ-7G607mP7zZ}a$mY1h134%8-NvX2E5*9Xt8tvPy&N11F&=ky@5)1 z!XS+pbWLc6JV)N5C$-Z5aOA60G@>BBo>K4 ziaZ!G^@%KlM8@&;fFA|4N!%T6i+sEy^ces!mqF>G)G(kIcTWNtIAr@I&c-i^q@d-o9=1)YQ< zc%msWGufJxmQkKxSX)}w)=Sh@kW5F5SF&?be;=@4fQI zJ0HIL!GrhTfAGa8Uw-@G!OuVW=vSZK|MeI5|L&^?zyIdJfBgRQ?>>0>oA>X0^xD6I8-(Hp9QJv3zmP>2$mR99-R%R`$%vw^J(NUJxR+PNBEUmRLu{JlhHrLo-GuP+G zR%aV4vSKQUGgYX}GF9iq)oP(3H?F-TrL8b=aY;&7RpyGS>}BN{%PTUwYjT&@uxMq*;LfuS~0SuVX~`zExTQ=LKQT5>fqi(JGLC!wXK^yJldLSDoa>m%@vil zbmQ{zd$%vV{>t^uo5pgpQ`m(Rfet{yx{FzVunRgEK{K>u+A~lF({;{5fEb<=Ysb92 zJnUo8$7suy6o`TNqCg+RVkL-gFdfGr7WCOA`lie!5%YPbhDzns`-z)W~7RcCR)_gzmS|I*7HBaP&j2mA|#azosn9S{!lF0 z^jPxS%R2INNK7TD3SXtxh){t*84Pd5Tn3Rl$`%x>N7%3lAH>Wkfn%6js;sJ@qA_bo zNlD4dQ2Lbo>?~VuMni4s{#~2cXbGXTVQt_3J?qau`xHM0U5^LXQ zo`2ycOO}w~+A^gSCY8W3=^4rPGfJYBQ8-4ymw4hNOv(~f5E7+~`oM~h2czi980LUb zpXmA(7?~%+fR~^tX@1y2X?lXm&e@Fe^J~&FXkLJ0V#Dx8BZ&^QGnySOk}89tk*|%y0r}&fOfEZ$SSY?xr$qgHUGJ~tv^p8%qE$=O^ZLw7}GOv_n ztFq>nC#2?v$0R1D=Cm#8TG7*wtxP*Ec2{&^3Zrag#zvV`>K?$w&j^qR5QEZ1>3fC- z6^KDYGdh9}W_Zn{QpsqOO$z$ZA+$+W9u)%0@B_>9!$2g`NhFpYNavKV3K;q=ssg$$ z-J8w~4?vM=V@a2s+(L??Dx@^&Nc0>ATG~1d5tt&=J>URZGwoh)?&Ki@ZIpBpX_Ooi zOA}Z93fuz>;wtnsoMBHB-~_I68RQQfPzXrJF&kNBtq=^u)!u!(P$VkQu(S;vqtMJ^ z6<7-+7=l*LyYODTAT_}4cq*!hX8=R+4BVPTfif@<4-ZL-WZ>bsRzw&zMyueh5hAn@ z01BOo+9r{T!mJn^!@eGvo?&ao3UE^BV^YslHQBfY)<0a%EdVis`BX;*GigCqQh{br z&mfby7tbuhg2#raZ4p>J7=(b6&p7SZ9ucE`96#_a0!BgfBll6m2%&TVyV&Cxl=iry zS0Kh-+lSspa1mB|N75=_vb(S z;@97P^zFy5zxMpaUF$}tM*2FcODpp-P9NTjZO7SDPaQwJb7-)0d}P^cz)hw85Ws-KLNb9~T$LC+9xlFpIgN0B;|*!!{XXZ3QJO zyZcb#ZJyeVld3x}+jIme@6J^i!Xoii(mZqmp}W}R}a4V=$)_MfAi~iU;E_M zTOZxMdh_&w>nHb|+P7}|niXpY+IyE(FY734uFb6}&#EcUsVUE^#U{6=q@}*1qqVMU zNo!yC(y_sw^%KL)G3`?3GMf(U+WgcW=9snsV)pLXuw(P&)Vkrxk)FYx#VeLHb~IHs zR~6Qk=2jPGR@u@k^U^AElgqObiqhlq5~DIq!O7viv4L(;J`2J;o(y)G6W}yE!gEfD z+w34`2STvxEMotKD&RgW4 z7bFp9jKv8M)&X^u6`;n^z8*a0<*@;zH5tuWXs}n9!Go=`&5;4|;eN4UUgik@@Bn9! zO+|59Qi35W(#;a<8x`sp6Y7+aWXMSit0=UrT2?(V)V^oS@ctd+nAe;*via1B?MI&4 zeC+6sZCfT5wbWo9&U`<^09G$Ze+{mLf?Yr`U>X55ARE%r%79~7sX%s) z7C(5JI~hF6^s;spLz(KDiqf(oOnu8MN*K<8GU@5*>@5I}$5!vO{^WBT-QCUW|#2o zn^RoH4%nHtij3US*n|vYTuNzWT}NjZJ7Bl4qrr+UYQoj z`X0P=HtC1(R0S=G=1o_jPKX&q=|3>i+GuttU8K#?_#~Yc%Ozx!ej!6LIi)3&nVg&= zrVxx<;WlpFLIB68tz|WR46{r8C+2c4L@|R(Mgk2N9K%9u=0rscB8m`&V>B@Y8so)z zUmhONz+HHFdKU$9Qyz>m<)wIFcti$?yqY{Jd0>z@BFm^KY6b~H1`4E3IK?HzR1_9r zsOto~0AIAP1f~Dvhu{GKI^^dqPMkQwy{Idk<52^0Bkm_b)rB^}gm#L?$0Z0jZUO0d zg$BtTr9o1-)&!Ka-y=t&!2nwh4Zi7zI1f&#^LTo%bLpS ziZaWxlM2(!OPi{mKDhnOm!Es@?H6Bt>FS{an;4&-Ikt7fnw5jA7ABTLZYrs) z$VMfTU=C+hFwRTD+4R`g3lQVw%qq#fBDIS@4ou-SKoZY_JrSm@c~%spTq<`hw@qwvzW7{`P z?%J|$_qO$Wwyoc_b=~%4ne)@)^HXAT zlZ=^`h}77Sgs8x{Q18eEgm%qlp^u4<3S;FJ z!$49}5;z8x42TMgb+C&-8JhH?I3_zgTkL#A4FiG^27Qb@j$A3(BED?jo^v!@n5mnUTpdc1X;} zB-ijHWPnF>^LDCk`v;jS;y=FvF3S;gd^F0`5(dB9cWhzpYE^YP_AxYIVgxT$l#`RA zpo}#g9K!-hfbyErK1^ho^IbRIjkfsoGkY(dKYr<=!ZCP`!JqH(6GzUTd-m?VI~OjV zN1}pbw5g@!AM9f^_jh2Lhj5IjWd1cAqckxRL?0tKW*WFmFIM^i$4rA5&GJ_VH#)Kb zyNDWwSP~s*Pt*~Ol?KYlMB}5Kk;uqFvx68wFfmu#wREol!4SsQOc1~^>{&X#W-Vbv z!!aY182CPE%_Ka}Ow90WqKx40xGcTG`i&Zbo01 z#JvD9nqCOsZ^NuwVqgQ@kPh5oc?%P_bUA)1epH4rdY$N37`*A9dT#`&@ckjZR|a)@ zAY&eIhf5%NU*1keO6^6bcPS%<8i43ybP`${t&^4^qrP+uS{@CKK10hRgS0>CLbO8q znB2iA$cCa1o{{{2JgkQLF$*)v{wA+B6oOk(nUbf43xS>n^}V=k!yKP z9!7Y|p#=xWFn z5)>R676FbiMnp!3;T|=B1xl<`Dlf=8acJM^;|I5GTD@f>dcw}3RqX@ai`wdoYDyTG zEmlidPGV$wY;dMItgEF0Wb@r;Z~yz>e)G$pefaJhH;*6Ma`W2plgGCW_b=*bEpBNn zs;kbetF={E<(8FXvDJ=vH({MG%Whfeot>JrsHyhe?d#usi2~)lFTVQV!KZJ3^2K`} zefI7f@4bBY<>z01`9;D@cb~?rAM0M z{0#^ zemu~1UWl(#cz}l~!Y?7lkP;uBmKbAAGG(R2=cHNkGLj2(trf+24b`O`Ep;oGwhgXY zwt8sQy77TcYeuF}O065+w02}Yv%bUK13jHspD${ts42@Y$xF|(CS)bYS}jJaIXXQq zGA%YD)fC34Z;3Xh?lIrP zbAh+lLKQq0;OWlKbD_VNW1x?7kS{)XoPr3xE(TVZdpR0B7le5`hWj`X!n{;qAI> z*AP$Vs6a0~>IMgT;*BQA;DzHmyw13JE({Ly%g(i;k^uw*WiUp>HXtuEow=twH?Oi7 zZO!Navr7cfOi6xLR;n5Qhj?D*MG|5{@g$UsFAY;@MNvjXh*zk=RZTpZ0+?yC<;3P? z8FMpZ8Y(k8T1vY*s)l;ohWpwF``U;4JNkOt>uL(q)8g=C!xH_7$Z&8>T3VWX&I*)4 z`vRJINFRfdFY`*+#|VzWG6n==Pya?7BcFdF5+x=DQHcy87Lwiv4@0cu7`msBbW&nD zR48T!#~=rUNP$6O(D5M{8ED`i1uIHC%@AjWMG`{r#7GiEs}S-;p%o3vAZcNUg+cmp zDDs&UIfOxoA<86064muHV2G6eCgMVh64^+}QaFcyiS!IS7{pM*pa3Bx;pHlLh}TqA z%8Fr>GMXr^uBifH0Af&nV{-~+FlKvwxF9pLJ@s83% z^p3=c3r{*k9wAc5##J4P)yNd;2ZmUeR`To947e#7xRzI-5Z;|iAd#3uPLY$VsAO~@ zqU02f2o7vuRM1eSNJH)}KL__BoeN1PkzY$p3)yAhM`7mI6ojh%ylSRQ4uLPch0OF5 zLx30-{9u>{j={dc$Jd+L0hov2i+;$o6JNL}V~B%sKIRt?>>Cgh7QTD)=70FZ@BZnJ zzx(3jw=SGMG%>uQrYy&r6dfNO7{%b^=NJ*_VzZhS)!NP;-SO!=xBu|VPk;Nfk1*uK zbKT@%XLf2tO=((JN5#q|H7ueQYtY6zTXjWNMMY*|VRBYx9L{HP;D+}$+{Q3T(Og$O z(!UDD#^sC8T)J@L$dT>)4sPljTwL2+lvkXRkQx;d;Ts&{9b~{B*$w|F-tJEBj&nVo z9{2ZH;Op|F=fc^(E>E~EoQ2-PX}*KA<6{dK%v!MUv4zf0I6BY6VA$2o$<5W#)5FEv z%gx)v#n;Q#;NuzO;~wnkYVdRpa$gwY9PMAh3T+aXwl}oYmsgkO z7w4wuq$OArOet|uNyhNR=&%G8@RA&Cjx=CF4Ty;h21@z_`gsMg&$F+muMf5<9zMRF z5?BJwp_jKihyDRRe*WI1kc~~DSz#39?`81!!lOSSB+!Q-=p@A7gAg9z8RqL2;_VXZ z;~L?QryS34KlczHk1&>1`+DF64-n()=Mog^?HA%<92d$Ck-1rM=_!#oQ_jmam)cUQE3zAEZD{EV^OF)RG(y*~P@m}NP((I3 z1_YCpm4!+M`v!O{V3evLiNH!kE3SwRU+&)5bMJM-Oa8vTa#E zeE7gtaLkoUCoi#5>Ec zGK-1-(Q<3S;C8WQAETVd$a-mF0Ll-OMAP$1)61&uag56Ij*RyVj@7p= z2FK*1%r2?P$uDECrKngl&j0F~no+(M8ZLqOX?O543$;O2@D_9c(mABkzy#DA=>kMZholaPMH~tK zBM)_k+>y-W=PZXb58(yJpyZV4BpBQ@fny|48oz=-7I^txC`!K_DF{(43_&m~1Z5Sd za?8c@X;4*uVt#QF5V*ub@DSn{p*)RdIuwo(-#I8kS&@vjCMp@es+C#Hj|nKlOcR=V zHfSU!0Ag4nR9#ZJX>#428_#|F*@NHz`rH5Y&%gbb|M;74K7WhpBwV4Oi5(wYet6G@ z3n%x#dh7fvFP!`8!9xvaT5zbH4c zC@%rCiqfLgs;cbb;?xYQNja1 z|6FI!*$Z4|&2@B8ZuMQn9qnAqfL$Hux;f2b88+_Suow1rosYwQJk@%*&SSf57nk|? zL2-0lxX@*RldH3d>+z=CPhz>P`hXjQg0z(Z!gdjs8 zOLYh^fx$sIK_*ryp~1|ygoP_N{G1}NnL~K6AuKo`JS31cWy-IAa9~t$AixN#7vktp z#p9is$-8Jn0Eebf18Bn-ZU_zX4K?_MhWQ1B`1l(<{6oC_f<3+cTs?i9-8`JAI<*Gd z+tuCO(P#=~x9THL?fU(1e$I}Pt@Raa$NCTK+Pb8*!DdaZF0$2@6;~AI=i^@^A-=k# zuqY?f;N^~YyVjZt;809t5UZ(^lVTDRBU4kN63rpyCDziSwD#6=Kums)1-__|t+-;z zX0}A(^AtB5*g2wN0mlGhAapY_!316r5ToN5tYoMV@C{>CSy`Fj7=be42M-)$ZyZCH zf#@<2{Y?51y-aWnoe`pM5+f*JNT=IEf@6q9EQp8@2_Uhg=;65-{(e<_wc#AHx%eY?`fU=_(1tVnyrKJP2=MXHoa!ndzlb~7@7 zK4xgRAIlixnp$Pug(fC5D;=9$(b*vFGcq#pg-1FY6ks3I+0ls76dbc=w0mmpAdV6) zpFe)%+Ot=#oCC)IVhHR@aOv_zOnr}^IEJA@VNn4%hB5&$N)uzXq-D(POYjJeVQG@` z9PYrmCU3}6I?E5=|QozQvY!<~VU9wkKYqH781T~3Bl87~|9Wo z=j!IdIv=160TLLaI8S#;M^D3AYkZEeWC_I#Zd~JIOuIJkc=wgp-+Sei>*r3tbnDVb z@7?<2-+umo{pUaY-~Z*`|KlIO$H@0Lzxags*FS&o*2`BfojGv+8EisU)t9DO&4I>X zr$G1FkpT+k7RBI&$G_+XR(x;3~X&U-_c>-LNzhOZb9OV-`!;a5X9HR)!k*Ghr2Ul zEoupG-0*w3;&>zr<=DIj5Ev3NpW{|Be*#G@#5ZILB3w0 zY*gvz9q#8F9>{nfh^rh^crXDdqX0)lNPJXid{mgl2$YFVPmIfE>%^S2(t<2BF7=g# zpcdS?5t?dB>MM&#EVX6f#XmbOAw3~BIW9WE7-5bIi;E16j|`1tQJChsmn{85I!|#ey7_!YYP1lZjx8HbzI1Es}XaQ)HBhQ{iDI%%a1> zV#CAnw#>#@62LSpn2(EypnPKZ=-^;tV?=0pus>daBO-CC6KDwY35g2u4s>((azr0P zmEsK#G~=aBYz2q-;FNH3b>IE>Ut@~~%zZYD4}ARY8@Hdk(o$VfRhZvUQPEggSzT6I zQC!4+6pQL>a#9joYbuv7Y7PtZF-3*OnZk^5;g$rTNf7qk7VS0Kxy2xmCBh)NyGAUp*+h(Ok3q%Oi)Br_RE2O^LNkqE(%D2DQSBy+8w69KjrXWMKD}K9-bKzCX_(Z${yu64A=!tj2QW1 zA_>mO$<54XHKc|)*e(|(Jvn8ABydcDEe9Oav8b+ZWyitY8`rPy-Lz(4*Om!731iO30&E+jm8C~$gpl4e3r&p{;vpn)MLrIC|t63<+%(xq^D9&ij8mX^Q^ z5KzhRBD@zdKcetFhMqzq-;^Sk6`)bZF^%YB=+D^dV;{r3lDmf+Q%k5`JT>2U#0u7U zx}&7wEI5We8u5U~pzh=D(cQWH?D1z_x%J|mYu9dEIQ7EyleeEg`Rd(g?>>L>`70-0 zzjOKhH*Y<)XT$j5($@N-;#^B>9nR+4dOEAC3KEO6jQMF1nF+y#R#S0Cd`Wgvl`W&D zD5o?hEicuK9q55w8}8k{*x6BCU`u8VimU76DappB#`5OI%1mnlvqix{YO=%E-O1n6 z$(Pw8Z$~fB1=_YjE((`;y8>Tuw@+YVh|QP+w0RbVV*-7HurCSp@%Q1Z8&fSfpJD#R z+uzHJSv4$xf`fd60zKKu34@_P{{S=}VQ8W7{U3sJKU5kKh9Gv8GKR3NcNo9|5CGs{ zhbe_QByboVW{wU|jEzjj#w95(OS6~(%`kIRnx9c-%PcF%EX~g>&b1a~r{!6bvr;V} zo|O0)E=h<1$AoivJPXVUikB%_ML?#%c6HPG*CS!uhgtNiK*tmqa*o4@)#P~Q| zPVfn*Ii85c-WDNAoDgrZ#F^t`W6eer!D5QFn2dxZlZh4bgk+;JB{qg7U`fU(EVU_9 z6|2f5vr%~b99m4#mbe&o^7|1C9Z~=w!d>TGPcS zWz0i3hR%hon3fLOKk1%&hlPL_mpx zR76c)T*3;bw8EnNqQX3ySxaMO&+Hj7o+XV(c_QD&Q6LE)XgU^$*6!i*+cV95P`2fcrR* z0do_0y*s#j4~A_g46aM9#Ms$;i)S zcf&ASW^8$WQf+BkzBRh4D7mI2wK&^cmYc%%hoxDm#Tlt3nbzWr^orc<#OM%Q=HLI| zRqTcN9Cvq{%YMsj2~=8~la>+}6o9@+O$PaUx<~-f1o?S_OZ>4E@pMIN!d~1g#%47z zJ6Rh1d<}lyAwhm2A^stuzUUP~Sp#hFW+iZh!3VcAQQ-km;Rf8Pg@-ARYT*$f*juO> z8D`PK!lo@lqfu)_8>1qPN)Zwf8yRVdCPXC0L?tlH$Anv=RZ#dN3Ir1t4^N^oA~80K z38vHpQ$|u;W=dRknmH%kl50)KO;5;4PsmQOWF?t1663HJNsa@=pp1#K7=bd8pcYF^ z1baT1iAga=C9sirtT8Dr7Mzh38=qv3PmZ@F;m14<7g}ZoS%5N1MLiRSlv)f~&MCFqHE3_0WR(M(Dbo4>>x2}$@NP2ig@1l5ZIE`i29~9zn9#)F+!=*j zk&QXWJU*t?S8qnTB`G00J3B8g4;+)qe(5IVQ3ivUK!7(U>;VBVXl0mG5-SGkKp6r3^cuPkLPL6%{)Is2qMJi>LwY)~-e;vp>m8Y143CUrm=KZy zf|x^*nZ$@bVqKz&m=$R(l9O1@0%l`%c9$-@X1k%u8gC$5!KdJJBH zmvmGwj7^ZPgW(hzI4ddC0N4c`jKuix#W)5{j56|F*|}lU8l0e_?V$0nScw3_z&Mv( zX>pZO+fbL7l2lw$fIbG9Lwj4+(Xey#YLqcdEv*}0_4J`#c)hxI{oEDe8<(zJy8x8A zdhHTWh7BY65h+KuCIB8WuY^h_BP$gv9KkU_8I&XSzi%ulEM6pqogGBDs6U>r5z06L*{(vGE>N~>k0A%z%Xn@7x8XyU3HFnnqw zD4l_U6vGT+24u1^5Y144s4)50OGThx!o6EqDfqCzM1|=yebbmqX;|te%ZR028!+8XPSHhC>RM z5;zM5EZlR<7oA}Mm= zLv_Lf%QHWe{#Oq5`|1xScj2+A86kwM$XpK9`)JltI*#FkQin2pc_?4Tt@UVS`0`M8 z6+sOBUNWzwG%*^9CI-71piEdO-hTb?1kXC_5?k(?vC+fq&^EQ<|Z+fNe9;YMn?t#WdJc~V({V`b=ob>;%i^hE{}~%(f2=?Zks-lYfoOXQ2JzSw5)%=OXEtm;V#5RDm<);t zV#)@eC^*6~MTaT(#HJ_$PQV!m`EZX`Qx-8=h>nXVa@G-1hWWm9O23aMsOO1v>S&d3H;1g$_-ET|UFJk3ks|hbHDH0{R$C1&N4J)!;5v1&cx?1O-+APgQRgA$eTWfVMUNp#_SXHIfj(N6nOZU$jWIDX{Cp4L7(fgvnXoXnrJTkwm6er(V+6_oUmzXFNSC2c z=|mTU=u^_gkT$v;p!3qH>8EOlDoANbAr{8|6lVp;AkP5}2zC&IzydiW1xDuuYDgkExyqhMk({EBk!-~J zp?(Pr@Pb&*N=~ko5-1af#~?)>h7@>vB7>0r0OX`h@XA9Zum;5p>C}Kdj=?g9NhNSh zUw=<;|H{GPUL1*8GgELwhbtF=1u?3Tipuiw$<-}wtyo|cl-QVBDk{#dswik{tsWcd z0?M$b8)$}&>z}`N_QrD;uHHBgj!{tN>P2u2Q%lS%G3QWUU(ZHMtiA@#pfXh9r*I4t zppblPOeVA{IBBemF+Vi%Wy`86D(ECY z{^r(JH2>1#Y3bky7N6jKg|}jAA*V>EWGPK4uD1|L(@=3IRI?sqok?1o{w5A zL%}g9U_dWQ4dd<28f*w<3?K$8Q8IvIBEy0(`HT)XFe=xS7Om>+*gQFQ>hSJ8TgJDp z@87nuckM`L-}1V~itMudgs2Kz`oW!RM^?307hB71DVV|( zXD1hDrIcl5ROaO7qk=V=OLKDGx_A5k`7i&>7tf{*I9=*G100@u-Kta=vbrC%p^-(tl4CYH^wm4qVmM4VV-Th!5=BH z(aEuq#DpZp1302E)FoDkL`x(+DLxuo8RnQ$%`tjN1KEIJ2;5x*F#=_#<2W8kA)6$P zQQ5d1+gG6-Q3?{Zk5#J0oNO_pUwJf;t`snqSk2qH2__NzkrNj zIA`m&b^rY5KfHS9IlLZ^4s?D0vj@){+Y=G&U6`AS9dT7zVX#bbRS6ik{H0eunNIo9|JxB6A%lYfEV0g4?#o|LmnNJ$W=Ow5L6*Cr*tBPa<~gIyxFvrd$Y#+HyG$GDs!7bd#xNg*eFERXxwgFAf*b^+tsn#CAD)T^RxRGQ z3lHdht4CJito((W=WjlL@#=Hu*kb9@m2;P`T+o72$?z^rQ)WPF^>wP~V2CB8V*8t( zYL8%aeT;%K8jewxF>wmS*y9-VE)P#0{S_0LAL(Q4)->6ri-O02HcC@Q_o!4X+FU8E znUMpXJsp5X&&WfU0GiP^(6|5%q}3`X0NACEj1XXH#A=j7m7+E0vGFzSOO`jbbd*%o z7L`>4WwP>$GIDM42`R>Sb4gh_PzL=0b0unc)IR-X&?1({V1(0$H=aj&AdF<-!5$^@ z$T-K7%Nt34$*Gqhd5B5TUzyv%lc*DC?TNGUgfJ9K43Q!a$>nlZz=V{h=a#`sbAE##+p6vxQ^42%Te73P(& z>lOHd+(+mu3iMY?T|$E+!a|u&LZ#vF?Z$fDKySDB=#Z4S$cnPr9cH(%ra4&6+CdOWbE!e*^2$*Z>I z)fE-R8N!-M%lB{H`v3j!|J(ojfBY|Opfk|7w6VT)KKd9h*C2oIP=ngJiBERSPT5>3 zHqyW|5Kw!l06@`{2TDtUA&5~-J&Xxh&c;V3nxoih5+1yg8W)qQ#nw1eTD%D!P{Nqa z;LRc$0wW<%MxhpM+e@?;Kp6}~05J^YDVF$DOMF^FT$;s{W{ydVkC~3+Rms@60P<9< z2M*07%Bh%CrkQ>eOsU*`Iw)k58Xv2Irm8_xk^&=BKWrtfK!$=E>51`Hwv|pz$Vg2{ zWm?KEq$R~m$Vf|K?j|+KoRSzn6XH^^!qGx%l1YLFUoji?*y8f8~W6tW;XkRM)$-qqe+=o%uq7yow4kzy12bpa1mRBj@$iwCg|z|R%owY%on-7_QVDmxfEY1_0mRUX z0WpHkY1lv+^fBao6vv>FvDeDbU+6f*(t|{%Nmqgw2`S=2Iwn0=@8;5lrBlPh(2GSG zLky3w7t(PI*ac;bkd9+ugaplS7H}g3ju9xMBNzs6dlCc#dJxhvgx~`mB{1#+DL^e` zfOPmG46y(X9mkMgzgAC#AyJAV7Vsg7_JvFNQi2rARb!io^m| z^jKCZ$yr=%;IkAWCpTi#m66fmv2oN~Ods^J9RX?>pv>|WOIG$Qg8|2YU`OJhLaEt;jGo&V!APvU=Vpyr94Q&1+>oMg?&X~2l4wF7$& zx)8*z{|ZKten`xaMou0W-kx|=NNgrVn+o>gkem>2$60wt85D_0C+4O)k)jpzqlmkx zA~Yf=6~faJ>%%QI#vw5&dVzWdn1^^NL@uW&E(D1XPy`XA{_RJ4ejxip;mIaB1&F8` zoB=U%M-C-}el0mg5{XnI79pjV^XOUq63NLWBH)Mx$G|*P+CztOp)?O2$51R}|03#T zG&H8yDvZ2{)T;e&4KKftLaXiC&J0V`k|iwNm`-8}2}0rnWdz3rLO}s&VnV}0uoz*W zVvdGYLImb?LIT`F{9Qr=T+`yiS!&c;Qw&ULDz{Z=`x^sgDp@#PoL0%!(5x=WOinb0 ztz6vv_kZ`xn^#V;Ni{B9i*l2Tb5l$6td#}1tYj(6&Aoi;)PMb_fB5e6k3PHq=1~9Q zqJnf&Owhu4vjTlRw3#D+V`!)`ESM0>Djp0_G|fj+Tr>d{h#K#KBWCk-U@%Sq1Yn*L zjgvZdlvL^mg$XpMftMFR13kdso$ z;N(z(stRgG!%Td>QlDtKn5Wa$G%3}W*%*USFjmP?ApxeafaqXf%#V!WfywbvNpX?6 z83{%Csg2bI82@%OlrL$j>|fS4Ik2*&s<@}KwX40cuA;D_D2EL}uU$U#&wu}SFTHTN ztD~W%y2xTQY+BuS^uXrmQ17AMrBiE1Z8=tO4DLPhax*hCQp+og@e9H@l%g%VW>QJV zF$#M{+9L6@W(>fK!WvMv^ck-n@$nHd-} z{a@5AI*4KHm_{_(KOM@To`K}7J&qChBEaRLm@!DugD`>^fDS@n1@HuL`p zkeRDEgam)g6r(_lJ?ZH%3XfcrFp z^fA_~q(WOpb5jL4hD{V>k=4{4wsukgh{`Js8J8R}5a+TUAWg&pOBWbYjSY5WH>Rk%2Os zY5KXuG5k6)75X(}UDzdN7YHCm=GP3h&=HEQ4#twY1xUC;x|8t7FbIkN*ZTE4)!?-| zG>N6lttPo@p`OWBOqjX|jlz$=AKXl*N<(Beg=!^DazDl2C zX6L3D9|OcNQ^|EC1%ZFDj$wAXl}K>LFz6MIDJ#yW@1}rZDBHKtcTk+arK)T@+n)UA zVht6E#_FDEOLtpSvax2eFS#-`(4DAdY%dVQZ0dA-b5FeO$jZY1{eS!~*r#4zHLzzV zt{PU%>xwt_Bw7wF&HY#Z_ILm7pZ}Zx_4ohov!A_l_S9-$cQY%9eE+-u8AD;*`XxKI z7w+20RAD9qGiTV1O~H>60Eb|Omk~DBlm{~C5O`KHy(HywIb=K#nBh9-*a$jPoFG7{ z$I@pxrn#;%Yv!GEf?c+(p99u$xYHbPOj~_bTYYs4vh$Jbg;5-)1hHi80xqtc+KQIC zO17q&il*v-W*ph|fm^T7Zvbrp;V4q|{~Z+m@ZI|GL!6>aq!Z!9qv zjnpuXxRvS!mp}~Gn2Z3s*hV>qGE~5A0ZTR4Rk&1S5{| z`;~Yw>M^K?nl&PJL(efD1++&sSX!vHWfM3=D;C74Yl;821fv;|iX1J-2;vwCI!Y{# z;gIi%2|*0J;-d_^@~J2mF&IyXS4a#6;foRl9MA><$Y9sU6wwKZe!A@nN{E$RB^asP z$p-0@4vxSsB*QMm$YenveKU>`<)DB+297}ueF`*=VPp&&9CP6!TyyNeq1ENp`7`HE z42|^dVmYOvyuAFK_&@kb5U_*Xv9ZbVx`uitKrpTa_wwjydjHz={a3H@%IkBd*Wj4X zKY#z1zxn9%uRj1~KKBkQrKIEIFzmmEAfOYn@kqth_@I!SYW9ay0 zfPN6%Ft%WvFE|cVF}&A}U#Tq83mr3zvKgKHV>kwLg8jhq5u0h@_s!3pM1I*U&&nh& zrY9|7rdL<#Yn8FVdBC_8`Uyy;NucZud(aYGfolix$1E%z92uYQ9iB?}kFmTjD8rcF z+J;tom)hDB1FZWyF~i7Uf;dBMj8^* zfRIZ79977iB3Oowl2r{WA*QB|0udJg(eLlQX^ zr%=sR0cy@2&fZ1$sb89XDZaoj#C@~#EFt6G`%TQqd?r`JF+B9$bDu%I+uahVJnjWC z%-<;~D#TV5?s$IZmZw=Qtvr8Qq^hu~&TWlV`H7|~rWy@05w^OzrE>4e)bJa3uim|S zvah4Qqq%CZvkimF7>N6KZ?eqmpa1Dssd!{h>GP9govlsfBLf|ClLIVq`@j9izyFIr z{bryW^HkQ-$mrTFWo26n@}H(RfisruVmXt%>Y|dG;?l;wmAsa+skW{)(!eV!TN~ePzT{fYKv&z_S471|~*Na3iiMGbTV57iMY`+Y=v+j{fZOsjp zO%WEEt!}ET0%dT?wANL(QNHt7I7=UF2vx21)MS0*jDdnnLEp*smCccg<_K}Hp&V3_ zdMYC&xI!|!)vfjJ61dDj!R@xW-CB12&8`|D!!bb?GP=CDXMz|3S50W+Mv+V0<1Rl- zKO(u{>{Z+WZH@JNxz&yZ@l*xlis;Cz+q1W}d=GQEYndWm>QJVtEFab>FWFU6w5_P% zIbJ(ZQL??Ywv?AuO?1Z>2GUc#9rPznAPjZ0ZXVwt`Z(nNr@#5Db4OPX&X3QHbTK@< zwro2n(;bUkI&=7~S8nYo+RYH9mPl>1wb8A+nrP*3H;Wh0qr?DSoH4~g0A=)(4&dBD z41p9F9Rt(T(}O35z`Sd5j6sb4)amI*WAU4hS{6-=MyCgb#cHs`!C#N{NNpd8fnY2I z7_-hXq89%50w}PHFBsFHBcMSCb`h*#bP32tGfKe+VNP!%jp&bUJVv&Z)Y(fx=rx5wY0aU zdwFuXWr|X%rm2Zu-er5^`YB%Qb>;H02M=EQ>;LAr-~9IDPrvwpQ8HgJ=J!j6`hL## z!3Q6_aN*+E=r{w<0V76YG2oZ6GR85uWZ)QPD%B9xFt%;oE3@v82{?v@l-8XwxKEy( zV{-g184?olc--?H{WHd>=yxppDqAS)q9xAYn3a8Q^;PG z5kwE78O2IBna1fu3>n!akpRljDMmn0q8(Dnp`vtB&d4R`!kr2Ag4(=du1s}sml$*> zalHyCC=*5L>7ew?Z45q0;Zr6Y0b}m`A>bcR6EagKV}!kj3z~;mjwM);g(nNazOSG> z7g=eUZz|vzDx-6mnw=Vb3wCrv0X0si^AZb0c#wfIs)-#!O^-P}_RLkIbW`&M3g@J{ zMUuH`x`*~H=$`wr?l39(B3R3q9;KPN3D&`bW4`}`?=e}4r@ZsR*Q`=g{vMY^kjSX#$^_XN#V0$A*y)xEV z?Y4$m+XBj|vJo&@QgLnuwx+sj2nLi1ag6*N?R4J+CA-3#+y)9XN8lKIB;uG_hcfkS z;02r!$Ua`w!&r_sh}nY5AUGsyX{c<0z1TP^MyacEz>&$05WtY5C9b!+&7DQ%*RPKpq?T#U}pa_QslPxqLXLrP1AL*MS8K;@@&( zhN@U>29BvIE064PqmCH(%xEFr4OzRlXm43w<(`7l;%y}b&+)!%R-dUa%j<|#3?`a+ z?K%BQ%hMw)56G&3_+uE!%WO3UkDooV^5UhFYqKmZR8d{Jtt(aw$1F?^;JFdUG}qT8 z<86K2sjjXBuf4y2?-dA!Hx&zFaK^wfAdA?=0eS#2Fb%(PaSQ|l$6&gQV|e-jF$(rj zRXb7(vImsk@YM`yq-wv`c?7i}t7#*f0|r^16&oT0tPnKt0Eo$qKnPNh1ve;wGQ=oA zE%1sc1YUt-P!rscPKq2Y7Mo{9!~j*m2l95HLn5}{hy+1umW!k4n~siJtc>i2O3*KP6m=L8OF)4{Qv+YLON>6Jpfuwc=ZRrSvhyeJzVzbd zs~6l$f|qAm*cXAZw?)PIEFZ;kw{T1%7VGWnImcZ8V@DFHj!tG>y9sd-7G0be>ppaF z=H`vlY?m(`#W(X`|95}-)h~bg@u%-GO6JRNKKcBMkD0Z^`Y|7V_#u~rJ#BAqhpHK{ zg-eE!H*(C>M|dwmhGT%3y4reZhSuW-#}KmPW9V0Mo|x=gslUY^6Hv<|#FOP15+6y= zz6pjib-~*X|n1FyxtS1gSxy6!K6;>fSi(+ySf?~oY=yXybwp`NZq=Fd1 zidD(47{&TWO<#5PHBI(U#D(ZS=njP9&{x3G;5Wk8$xnh`PR1XTSv+P7Yk_3e4Wm;j zKbWD4J-{%qAS{Loj^TCFrFlCUj1q5&#G7i`B5qJcV^!($&6Iq%A0z4_Be z7xyiW^{`ZHJkr)!nT*lNQ&61u95Z->C0@3%)GXaeEHYbFQpy&opdW{qDb{1%ofUu7 zwV-h!p+t7AOGOS3nP*FME)&m#f*g>Ci^;1pGe8h<2JakbuCIh(+5=aI4iRUz2ym0# z>g(2Jcx!#DW_`T%ESA?XS*9EZG(kT3AdX>| zL*xw=D}Az{mhsBCdE;)nxSO<<9kj#{Y}V1iF|)U1C-a!_t`%&1x-8GVl&Yz^4B{N< zjN*xz9O<4J?;9UVuP%<=ymE#G$4(xezkm1Q^$Ul2xl&cxPToP0j7FGr4e&9VnCaQo z6{X#s@!6@->51XDUcdL=J8$#uh1SLf=FGcSGQcr~#rPK4wz_vsJ@1Bn1q0amZPWdP zKL(B=z%h7YKpDBB^#CO18K`F+jmU3SG&dTZwRAlJ)LPY$0T)9VlVKOAMQ#{kaf}2F zjsaFS3nCjZ1z0g&L75a#h5)-DE5I~{I2@8!1_9#=h!7A6Kn#Ih0YnHvNK`=61c-;y zvPagbMJb{Oli8(ks3N3q3JB6c%|AO?2-HoKqe75L0bJl1Vi-u^f@}erK}JobW&4$Q zjo~@wE}g${=FZ*QSFc^d6}`ALhe2FfU1ow3OHT0XV2Th95@@5lr<2J|D7zVOE$*$? zEzOZctZ|?(aqz%2?}@y5?ZojT^9cXuPe1$huRr?bFF#_y?^j=c zlYc_tJN}PbzieU>7D=OkOHykgtF)? zoZTuw3OZs4!w!4I=$@-$s+CHx6celt2;?HDG-70{kB-_Q9SzhU@yCci%-5n_gAxQ| z7awR$fnp^~&94I$;ClV5&~4P!>2gA`aSV-lZefZ)B`j^pq$D=}u*w6^;~p7~fnfMk zt2I=Z4OF8o=-O+<{Ltp*$t^eo$ z{D=SjKm6?gE5lS5PmQE+UOUN)a^8O9=HLJOzj*VtYY8T1cQ#Iqr&s0%Cx$xUm_$3H z>zJinR93JZf^jRm@Q$HiLEEYlmTX}m+P(BB;fw)datTIuTK3+L9SsDVEVQh(I7a>k z8EiA#CWvPIVl#54Kst%41HVWeFCQ>7AI0Q1*10WGzrHopMcLe;>?Yu_-K+o@@s0x2 zSm!tDwmM$YD6N$H}(gz79}kdc0?Oeq`VB1n*0~ zarx+#^M@vfJ6jtnfS7oDB%N%H;exBHtgR}q+*3Tz+qp11!OOOO@ySo`-MzySh|Q7u zYJj_lzEH<8Ea1on${5G+!^TO25rJbM7y?sDff(Z$9)mmpiFxSh&zl}E_QbHKkXpJu z91LPWmfTJUBxONO#|MKlm3J+%u@ES0MURe+@I!%PSnIaB zrV8j_Obip6E?zp%Q?W5p&-yR?qFS5ky3=h-i^G>L9J+qx82`KQD1Y+vx4!tr!(aXC zV^HSHuYUgZHy?lX)u+5X@`Dc_zWvS{O!;PA;Ak7`$T)}zaZCte9Kqypj9US(Jdf?$ zIY#|We-!0>N9G~0q3g8HZmwN7Ln37v9)A5a47CuYGmM5FC^&{rsKwQ_rPTv-i)&24 zPWKGrjN!dYbS<&*vVxjO3mas^;=fbV40FgVo1I~c;Lr9v>w~bVDY9~XrdKC}GPw}L z{|^EU*gs?_qjZ&qA>>2=4T9>=1)9J`shuO}!fh8F-5mdkpr-(_Jspe^LMckOn4>C3 zcTW}2*(r^{V+Hds2$0NC>P(;-{+GfofumMoI|~9uQHTY0bB~HMbUHL`*B4X=KgE}o z3)WHhlTN2|sRCqI2^$ZkqLIsbw#Au^>U>SMjhJDP0x5R7xil)9Jouvip>ZRv;^?n$$C#oK!m!Pe2rU+TM8&vv%ey>NW(@BZ?) zr}oXBJvjHu)l1d$FA$6&i@J>z%M$~{XpD;ub}@({6IonRi%F^^}I ze+kh2^ke+)+mXd0|Ypy>iJYQSV6 zQRxy)R%x6<CjVyedb9*olM`id8a)OotR7NB(G;^2w{`AThg?%vt=q zgo0JWswW-01L!MDDBTpeQhos982Xi%uf*~jK#W`RE(k!3I0nx=Q$NHptO!SY-um=Y z%QKUg&YWDBqz9>ODBUrbj*awm@H#*S_I5=hYcoT?|J(oa?7@X|hvv^8nZJB`?cLXI zy!rBFCMYpcWo>DEcCv3~visQKxx)vh7iRlM2IB)vSxPiCR29?dz^oSBFhC50Jy~^E zwh)eCIk=j#GEfGNVJ(yPNW)_|#^(~FkdOeBV0!T)5DQRJ z5w+yT9>@6XvYxRyVn9P8a)31skCN>fj)}LzH|v;^i!%QtDRv4Y7`rpNQMz!BvI`DE zDsJH%=96nGd%!X3U=qh@_BAL2wb0Xqr;TAQY`ju?=W|ctq+!%By^4&joE+_%ndqIH z=!IbDaGaa!2W~(aoG}c|X=|=;DFKhzM% z1YJwpG|-oxQvxQ0`AYa;=uxtnO5zy%FXx&`5O_ooXhCXOYI-zJwOKWJo;EaF{)8CB zU_`AK$pqsV(Tv3qjL9JZw+*=n2u3a97-CWsAQ%M_fd&GGoPYpQ5Qq2!m>?w=Un~Xe z5O5F+VsuCa>Zs2yk_9~~98J|zXGZ~8F$Dzk!9Xg$45I)m;0Wn*u84A!jsu261a=kR z82M&E869Pp+HxnkY1|fuywJM@$6UR3<=F9~yp$I+3C&DSO)$+(9259s8d!va)j@B* zc$HOWTACUif7I7C)>rp*wNFiU^YYqjmyh1KbPS+*@b>Mmzxn`wjC0BS>QnqNUw{1> z9K#!zaLL@bc^zj@dwV-1gG&a#4*g0D`wel7bt*l^9}^xWlgl*!c#e^^2yDlCWHw_% zfhK`9RjW|*P^_Cv!+{RmXy2vfnR&O3PRypd7y>uwUV@z-XlP5;wV3ko3}G)Ymzrt%6{L|uh0 zlj}FZ?gjUUpq3v}utOo+YsaLm;g&fU3jb!le2Kh4{l-Pp|O z;hy=4{@3qZVLmO3$Gmy>%Irw$=;{P-S-N)a!1eQoE}z*y(icxf>-dv>c>gRLV<491 zhA~&e{fW+aW9^>&q8-l$9Sz&~r;hQ1VDQ8cV*-H~=Z^`zGC)jgU0tlPG1}0unLkF% zAy70xofW2(~PyWOhk0d~tS2AN(qD?XU|e zx)0ig2q750GQWcfmkcTT9)o3j*yWWAg`|Trq8z?))|+88Hwar1&-kxPo+}K&EzSEKZe&W!7=@V-A9fcICuVZce)df zp?8V(B-5#uf&S>q;_#hYXI^>nJP)z^uU!7->kpkX=9{0xF$|IU;){>zSK{^8@4ojA zC*r>%eM-!}jz^>N$B1JXBIA#b;io8?35}1jex)$S__LOLIhSu9pAzK#j_ilCW?ta; z&7Mq%8OV?zLqbf$P}@)p#{e8O8}wPQcYbkcc5aEaWF}`8dk03fyf4eiG{@3S(N2dl zk(Owpvu|*8baKjhUKZVAbZ`qz&c*X?sPASR<6{c=q99liuTTvH0*Oi|MWs=`D(_zx zm+W7)c8PU2WOOC#kliyq5oDN^sA7FJWzUVJPr6DbrW`SZ?7d9BJ#n zn%&%U`6-r*L@WFcVi#YTTJb2f=OB+lS|BMx87p6pOG~u+P#LSaeIu3<{KVG#JyFol zk2VI!EG)Uz@bJg*3LacC;0qALs=f$3@kKDq0byY=-uS^k-J;#Qu3x$U$}D4E(g_wW zTbv$Y3d!_H_xWS1^J6_@J+b|BBg<30C-zTYJ-Z)&%(-JrXO1lJuXMaPsODMh14SWLvXs9j#4l?55gVbRwxK z7qXpQ>FjpKoTlxjf`Em-KWrkM$=R|GT;{ zzA(#RUVf*Y^e{2Pm+=Z6u@*Rn@iF5g{f7=Lvgj)B#)4xi_LL`LQI-i{gJbv^Yh(;D z93zMk$FNeF@CAZ#t4&N!8pr5)s3#t=o~U~0>FJ?I1TB~LsK%Sysbu`|2MGcoA73mx zi8vTA$+F7Ca=j2ELphjgsKu~GD8o?_AqgOcAQpK{jAoW|+~^i*A}Fw{LeLS%h)aB+ zA>9wA37{yDMSbE%xFLm=fiPIyJ?;Z{ zhM4g&xJei*!^jwh$l#K}z%gNs=No_97+p&rQhThqBNb)f;Po3<7UpJMCs1uoL!>4V zi^QXKxR76e_3FEC-Z^@3p4r!*efr>czxy124E;)MUw-)s97CtlTW`O9^VSVkT>)Z1 z8K!f)=}Lh=29z<55zYKFa}0(=_RK7bgw5=VnHJguWWX&JzK||~J8K+6B1qyUA}uaW z&oSC}3eO8Dlk6FerutesdK}6$wKp;Dx4VCcC4OgT#W6HF0)^B32qF)R79~qodVnbF z{YO5>NP$>7ir0%;%q-?>CUZl9`YY&esM*^cv-@U(9U_+%i0mtb?z7!(EIn!{lcFb! zjJ=tBp@2cmhUJiGr&dv$sgbT)5hELCaJo?7jD%34?b;y(9)++A0f_NA#*`66HVEi* zQonlC#BN$hcnrrZErYsl=>Ev)AZ-}uDkEc9zMTNa(6AwxJ$v>LuH&Vmf4~q`& zTfTJR%!woWhx*d2BEPmUxjZvWztX~Z@BaDGWBaCfLBYYL(bd_3i>FsFpWS!q^ga>~ zEKlrT8b7o)yF53FR|YpsytTHzs+duq^deOjU zTr#BKB90Nn+`oTcEBWGyL4amD5=qu2;Xa7%h?%bh$1nnyt|h)rOdEC$+Xqkl@P|Jv z-&4j51X|l0iKY8!rj~VBC|Fu^ck&{ZL=vr!~b1DetkI^_^ag22>u@oLYA)Bw1 z@y7&jy53;kweN|M?0a8wkLKzG`tH31zAa%_Dg4CEBAQVlMTxR2a13`4ph1CjH4pXv z7~gQCnQ{cj(6ux^HP<^hmhN@S`|`4awp3qJysM!t!7C&?I(r62Mp?R!5>>2mjJ_ud z1U%gq1a>(!furd2Eh?5kx+#!u5EJCcP?7$ZsOGvTyG(26?rMXeyFsj*6S`yU>WLsh zS*$d6Icf@iUXwXW$;2p=s3(hW?3GdmWV(iF=cX6l^=>p zR|uuEn>~`r=yQzvm5f>}uVsen7_?;tJp3^%gvu+g=~rU? z7y|wn9{O+$F~fUVSPZX>8|TY%lY3dbzj|VH@Yvz~r;Z(5S(sj#8)pf-x$!=?jdm|h z_8(puKe9S8J)B&d8@zGx@XI$(pFO(B@ctwFWEx*df^y4lE4C(ARTKH8JLYnunl``rd^4$)@GQ^7-NrN z7aiR&CJQ>4Y9Whu<$HW}hH6W?>6ij3sQIX2xg_Y2#i67A zuCJpLsc>|xe5-&2swBwM)gkM)=q5-lku(veNW;TQh*+mH8-1{ zCdLBO>tw3{gSo6*Gr-H3hWq%vWl&~xfa%s{#d&+n3K<-OKW1@*NV09+)1G6Z%xDg+UxAP2c$3QJi#(w?v z*AX}>8DV&6KTSS{Wk4k~0tw z2tvOSbKu%qYTH|@=?Z6p!n<$3bm!)I7Ls}O-j&Zjdx%Tso3GuJr7ynt7>;@P{(}ea zzWv_AcQ0Ogfwx{H5()67rDc754E`96^A*ixM#faR_tS64G3&Fe%Zga%=8@I#d|r7H zjzQm7D=&2YO1@Q-jCCP!2(uyMA=6HZb`1hhkZk3!tJ{hoWsUirSy-H&Ul^O7>mQzA zdEX=}&_ch ziCFDc-*iZm5{y^OI;z69D6{)?vnDFQMaQ~V3$KmMAHP( zfOaiW3fd*Rf)cHK6Ht?;DnP75#u>g~%9P2qpv+P9iFxo@;GdiYbH>OYG(WvKHwDL>J9YH(x#MsN&X}=*4u)jnahVBCn(c=sj7_8(fE z;zc<)WBR+Iykv(l5cxZvF4*xbLp#+Ife*&51j7`hNW=|%2?V;3mM>51R(;aKqiYSpmYu) zkWob;n~u~}G0Esi!PKk*Apr%-RI!}Gyf}74NYoZev0W2T+wkn6ny?Gj0C@&9e7V}7 z7Lzq5iEmSbg^BeW5YrF`08~N`6!VyNZFP%BLpiLTOsCS?((FEb*;Au9X41(hqhtmL zy9Wlk`uaM{$_k2$ckkM@wV+@}cXtPWtP2WvGYN$kYd|nU84(OJDRd=tb#;YiDv4%@ zff(Z$o`J5pWC!`u#Ow*6hHOnW7h(h-PzV7T1i_#Z5ZLt-g&jf=IZ-gc?4k*XAQ+U$ zFpF1wnh~IgX^2DAVx-~=0vclJLok95Vqk*Z4TF${n4`o7CBUEvsy|Mq(Y!ys_)xp?&l~(J|E25NU5~YHhBG$Lo8#+Lo6_ zE}S_C$Ka2-_sZo@KYsVG|N6JT{mtiWUk3e3Kn(p#@4okdF~$6B)U`zK5;Q|#oG(EH zqaG!muDHDk{Aq-xaE%9BDgGEY<2t|&!>O!qLaTv}iP_WH~v0}&?#W3xFOC5vN(CXeSBG7?NjyTluEjIPLH&PC9! ze`hw6xj(vHmQgotGyTo*0@KbRGw@{BcO-xyUAr3=Yll>bu*0~4M1r4@U0+9<#HxUl zxe5Zg?5Hp3IS8iMqtNv#1;I~20Zl)noyF=yB`yw_K)>a@G%~xWj1RnQr3=l)t zk{gBo*0@S*j1};mV&-*($OhYnqng)|6C-BV}vHKi||E)?edNL z5QDP3IHt_+LBnXW*jcjszs*P{sl&N+$+cjAIZu1bK*Ehyf1C93mhaiwH-2P5)2`U;JHU zG>HW$!VYKyVZ&e?gFq0Mz%B^6LFqsYhfHP{S%5+en20|NWk@v8K|mQD1PgvH;~26d z6I9yWJ1^aS@s4;AB4Hvlok|S9y>$5^9Y#DY)!_igbfvp--N7-D#+t^K8vHRmeVr`$ zd-tU~xa(S*o0zi{ZL4od_-xH(Omt7V#eV{bfkH$lYN8>Tqf)bU1On*<1acu*!_GC6 zc8xluYv1e^+3m7>Wd)Maj^+wt2(f~H)Y1_YbZQX;DOM9ZN{R&)#UWTE6iD<>gsc)! z6Jbc-2*b+Pg-AyaK7$g~%10JG6BUzgf;26o&cYdW7QbR#3ukRm)-^Vk^gVW*7uFnLNngHV5VpIkhu_1~&-}11Qq|C0&G?wEp5)5v z;yXWnnKG!!Dl#veJ@no?FCRa)NY~Q)@7@31Z$A6wHy_ir^vhrV zLgRd2xp$X-r8nPt17ixrM59p~A48{-`D4T}JYwaKaV{CpALHI95cbEEFaRKM#+aie z>tYFaIRy$_l?CU*$#RT(m*kI;so-Z#kX4g8vEATECNfLIz5|pXU`=$Gq7X1k#Abm| z!!rXi%&#o7%`LA?Ev}4A&3BJXB>G0-m_+Yjyr)0j)e9)5dV7W@#xq?@LFW=2!$yOo zyEj;g+3^R#QAswal@jxHs!PgrNFi_tT_q|nDF}Q$1{@~%H^eSP7pT~7!iIvMMMc^D z67=iJ}T2g?7n^Ab^nJR|<&;s+iq#I}t}iAyfhFqGM;2KD#{KR002VA`ex= z`jX^{@!7?feU4EUJvS*t!OkK<70^X-MY^=ym_zO>b1Nv!!!h(OF@BPltg=2g1e2GS z#~)h-K@5KvXn2fwV*m{=xc~S6?r(ngyKipax^(*F!O`I~uXP+7N_9l*rboM0=7yPo z4a)3aoVa%3`1zCjmS*}{9;Sm=GneLVd**wr;))LjnHN*bm@y{CVM@@K6m4jXH8yEu zMp8#hOJ>u2pTN3fSq(cRnD@m5v$Y!vxdvFqSX_c7HcSx~uuGyWG%Uqtno4I^nv{bq zolvY|RS2>4sh$dF*RKPKekCQNqtmHm6{u7DvSl=Zj8e0^!96tD7ea8OLzJTubaqu$ zi8_Uqk06_21IplcWGWM5 z7x=eLz$L>&5|qKD5s-s!r3}aL0CdeIXi#cg#A^6zm1?KfsRYD`W5hHT<9%`bk`u%( zfqTXIR}4WA*d?9r8)(DQ1t^LQO;8Y>m>Ma$0R$nSNy!`~yOp3$BC(6;M9Q1RxexG$@!GvtUjd@$uXR&n1A|^mklOQGwgOc_W1sl5@U0hjm+uCZd?VDR$o0wnf8=vYJ7>V}{ z!7-hKBON{c?VX*m&Q!X;Z)|#Md}dmsWN^kX*-8I1ShbKLGFf_A|KwX#(Ekr&Q45K* zWOhLrX&c0FNF2lEQ$q{vT2r^{mB6(qgwk_&P0a*!Oy=%|vT%qBs3x3U4;SCYBMT-h z5y8GGl|~`tr5s{H=oGmp%~jA@NT(?D|DmfJEO6{Vk zOsJ}=A=l`>wSZ&zfxt1-GZS_7wZ<{HSP3+2T9-z~&tvIyaz?AZhM7lDORzO3nqimLWNTZht-Z57+S%Tog3;SsG*p(cy|4?s5<;2K zu9@)12r{}BizhS@2@@+akhMm(2}%e$Dl@Fu#|TsQ75wZfL101osFA|1or@GZ>epY0 zK>1cOGKuJf$_(XF7E|V^0gA7Qth*rv?drCul7bJbs!naW{9VkWHnc^6pb$TA^v7iQ}Hm=sK zRvF?L0~ZtIn1N%=`(iL-4jA|YWC1ULjDRjOUK3Iv3{nIxAvEC-JOOHuE`kXu*e=-K6W6UcUYED=)EJ4POdBuy{PKalZOPNNh8%86u;< zi#TKG>oi{r<6!<+j>+-Fgk3Tjlwmv#+jo4o1V3~$8wd)yRsq1Cz5NAbjr0yixUdsq&H zIka>N&_STSB#aYQiVXwC6eOln=tPM34 zqViP;8N~rAgk5cxMO7sxMOSJ%A;AhH9c7)4jGWZY$e~;e(z#R`vQ_di97CN|ZAwN> za6<}$AO@EV8z@5ulh_x>4E;*1m{+jt`R&g=Rg|~At*MSBeOH%eUwGm4$Vgva;kMnp zhq5HEplH|jZCjq-`pk}P&j;N~j$lMHaEt_uM=HfD>W1i7;vcz;nS@-9q4}s;5lf~G z(zLD3syV|e1j85e$|x}xVxXDFbBx$USOa|cC?hTrg%JBkrRFPhQ~@->G)tdi#V*cT zW3K}qQp#ooqjYpsj;O^)nOu&+abm!M0E>VZkO%2-53xAL*hL&87U2-cLM{s;7)#Xd zW*h_AFt9h^n6oTuhZ}~s4cxkY?e?9UhYs(DW88#IH|)aoMKBxlsb{_q$J94f#F9

if`w|TertXMi}Y~$F#Oo!!hk`m5Z}O*Djr)Q|bJ<1J|ycVu%cbW7zP=h-2>D zy`{NPd<*=j_@#+saK`Y5Ft=Yx{unq0cZ;^-k^(r!yIM?ZR-*ybU})fG@?dTDiV zYPNT5imhvSoUNm8uxn^2o@Qmd=6Gj{Q8Fw`$sY>0zAr2Kib&iWJ~!~k7}EeN?)#k2 z^ams8ABmxiXhsBM7w-Pn2ksD3ID~9hq-*CI3Ay*-4@%+LLD;ZB3g?UpI+2tumdV#` z*PS&fcE&Pp*{jD_90XZffzcK5b(#)u4rKVbzsOn9Z%bL zY|G2v$yDvb40{>xZ*Q#|9!yP7_Om43v4c#m-iI6J?D0eUmu9C&2jVStyex_FysXm8 z;%2N70>r4J0fON_Hx|p;Fs*gl*a*bngAu{>Bs$o-|uP}X^sS7$_r--$Yy z#5DYVG%K5NGdN~;Z{LDrh8IRM2b&oVYikSRQ@n?+rM#kWSKc=KG25Ph);VLgK8F)V zuRjH12yO`2jvWk5;9oLJrO~M*d{L}UC7yc(d+5=Q>`{O~i&Jy9mTMdX#01?+F2Vt0 zD1#u5!8DpPMuJer`jxPJ5C+(RK#UA_2xa`3L!=8k5D5NJU-l0PK@3wwFdDETl+huj zKRzaxPcZ6HBEEgw4ce8v1&>RJV;~aqvPcsaF-HpmP(tuICd4jc8Y@?)5qB^T{+L&2H+Sr-YduGK(`R6TiAr}d4V@XZr%1wQR%Mg`m(logxS~W zt|U*?3+G?pahYVftAJw|9|OmX45f}AU1mYNJGailF$|HRU&&3q{_>L#K6vo@8?S;& zOpL-G!xzC1369~fAVXx}7#^p@HdBc|ioQR_I7a@MjX6gC6^}?XM=3j}$>W%kvQpbN z$>sbp#xc$?1Vcvb7cZ-3vC?S(vZln`BQu{FHT5X1WqMM`vTy$y8ytgIh9NR=%-r(Y z*zCga&*mF23Nt zNiV=L+UTzBm*JC|lu@iP4nLnL}h@S8f=4 z@cDw=Eq=;ovd=N973U)OcR;f0<}NK*AWO{7HF|;=nn9j<8m+?tn6Peht?Wwlrn(+}PT8|vvzj*G%!Q%&)SLPVIs({-!c9gtCSHA(JyYP4#+NH}C64keuX&(pkfg9hKchpS)J4cC9pD z2%U5@O)C(=bSy6^X4EZ_O8O@X$>e|4m^HKk=kvK=zjM<4JW-BAq-K$TTi$|vt{upS6A9gaC zwE0Tl3xOvd&KMqjJn@KmBI+UOno-cw)%=N#W32IlGWcDDFXnnd5Y70VN_I2^H1t6b z#4g4$P{@YxVJw0m1+W7deF;Jwi%C}?1qC692qwfa9QD(4W%4S~=NOPh0m6VhpbapE zz^-A6(uE)-8lWhh*fiBE1khND38+zm3Q-o+fEbO2L9oE+7DlLCyMCEby(dl`xp48! zm1{2mF_*7ih{jvSCq{VgF>;g_M)GyX6EX02+se`}BJm^4MzIRqi<^=@| zz-o+CBodL1c%;8KcI42)`w#BHG1sr2e)q?(eEP}5Z@&82O;&pUoqMmo1joQnZu#IF zH!v$KA>-z6XF0~Ltrxr%(hcklf@ntm7;~AJKgM-1W&APDTa#7DbPr`GTHAnMk7L9x z7H7~WlTpl+;TWtqL53Vb_CvNr28I+fGo+{is3p)mXeV4J0y=17B-yao!R8=Fc8F26 z%s84~S%qVmxHK`dI6A%5Gd$BfGTSpcml~X)kEyDuwXCM5uCvE6@cKLsVz#S7kbypUJL(Op5BDL)t~3O6ps%GX1JrIf4=nq0Ft&rRk`hNN3@UFo$}A$i*(P z=tO_rko5$#T{|j)qZ~4sT>@q5_d|g?kuHHM>8f3|5A4&H`SI}H^flgc!H;Z38=e^V zjW5o_G0Us`N@iF;27gR(Ns%_3G5ld=00A7sJP_7z>h134KLoBCreAk;bqx-&tm<$& z85`>DTArUevTy0kv4iK29hw^*Y!rn9rj|waczbsB9w4T?IFBjWFby3{ zGgCvj2~&wS=3qbj%n$L$FvyqAQ1C?%Lk!0d=w{;C&M%pMC4ZWdAV$wa;~1W7_DHeT z?YC$eshTRz7*GaeA;2i`3IQ3o3Gq#cV6?08F~%`s8ZnA+1WX|qn)r#|dPo^T83ep0 zFo$pi*|-FPQ7}wF;HY$b0hz#2^bt@{5V!y_aE7CpfMcKy1=1z>P$K^d=_C>>uM!0- zQntJ*fkSuh+(DM-27e4wlOPxb3#_Qiydj479zSv9=<$R2W3J!2_~PBGXU?5qkr*a7 z;EIN0re~(`$-yys1v|FydKQjpXsYGy1gXx%)a>-3qlaI(cwuC8xUy|_PCVY1MS2?55ea}4@iqb`#wsbW6Ia7c+9<+>DfvD}S6B5<$FW^b0=Y`GM4I^Al+ z3oC?lJA^@{9IW_;5QAZU#Fl%z{;5McA_Ec)hTs@><jRG^BAwKj02LKzVW9HRo! zXYxE#<)Iny#b}0I@=|}@PtJ?XeWM&+sKnZL)zv)Y_BJ=v@XBi(GnM5i?@DBE* zqg|;O={vSR#}FAHM)Q?m7ifl{!7*Su5Ak$5O}~=h+~8@#xXF>hWJ7vT}$d+vS~!n%;PymTms4sJ~XA3b>F5IDkP6OQ5SORcSu=9ZddqIq#)3^&XxFJ0lKlP})9@Y4_8 z`PDa{{^A!Oz4Oj%z|)Jo|A2A8H?Gk+$YY%8{qn~EG2$5fF`^lHVxSr07~w_09~*H@ zmRd67X1v`H$50OAX)@&m?i|l^<9s${rR8kj!I2Z+ru_e{6yps#{e4HD$t4| zQJxqehAp=oQd9_8xQ(EUDq}I=0>lh-b=Y(>#%n`1>~e_g{Gz&|8NT5ZU=uG?YN4Ac zQjJ$83Lyo~o~HV$+R8Gv@{(Q64V7)pyq&n3cP%mRnsL5t>PQM4G0qbM#O&O;lizkK z80X8w5R?(b@NDE+$8%2)L)S`zVSltQ+Pm7gVl`563{9(z7s%9jsMO7KA$TYV!@Z#%aI<>I8$Z~dP&z-5O zuWo5=WQoPbrmA?f0e|$V6KhOXx^?5+i#N}|cK_DrpMLPkCm;U!$FIM7|7FJc(y0W; z@Fnu)Vq9>^FzK2;dV&`7MbIc2dX_>Q!;f=Qe~bq%VU)?j3P2NN4?39mC+c8=Sww#K`t?gNW!pudkW=y`RR^if}cLC`tt1OS7Ud+zCi=btUw^*nAEIEDc+ z>IlGYVaYOEbAwRE%~6s+Cg7NkSZh}*4!-nuI%f<*cd{d$h~tdWn3(kvtf-BIC!q@I zggC~B7!-6mtgpFGHmkssoRPf3IBfrh_CAz|{bqw^D4dD`G2QLWY$S#>*_Fxn(*+`& zYaJiGPAhQ4SN3IP^iz;YRBTs)phOYOV>m_`IitKO2-+xtUj;{5#*nwBYe_?xhFwrb zqht{1qwMQ&Si_cNtsQ_V)&jmT;*x$PAjS>73_6>Ld2vBqb!mM~S>>K$`kM;#_&2u` zh}rJma_t7hC;&0y7<`SG7W$QPIff^m9)`qvq|>Ho(ZsYt#cGnqG4jMHhF3z!lA9uq zF?_K>zM2lL!7&==iw6Z(@WDm007BSd=Kos-ae(DAEFhy2?U0IM7s1pd2r>j8rq3az zLonumL7-R2AO`FpNG&Az6+pIASou~Br4VxmI4R{&J}w!J?G?u;hCkpKUiZiw1{l}} z$DBNU^wgPSESd$!BvWy>pg90DH^UcATvJ!^qi6mEj$u__I0lzYJn6cYUV8a1Gq+=L zR_Ls89Mf3S(p1fIGW%Ai?%uwLOXkuG$6md6gL&7Veg5I=uXD|J@W(Jdh82YQLiw&S zi^*h?u6YP1Ael@A#}IJI5I~tH>Q{OKjtTrO8Hhp76oU5jzx+myM2Q>?p*A6KK1q8GD5;g+@D@4VzYiCp?$!KR( z$x}{mW6|c6N46UKcVPo@dK1$a8-Qcu!<`IsHm(bu~3~EybhJ+KS3_N8;AiD<6IE z@U@q2(W8XPeC|iz{n4NN3kJlvmkdOzamHXou`V(*m@(gg0WsQO6wyqQg<(2k^d)Jd zM~U6ecsmQmuyPD$FL#r5q~r|`g%X7$exgq^f*4{Y`f4HBrk zn!zz}jN1Z-83n@4e9QP|7zND8-=h4T`MdZbZ)K>j`jQj}7~}jga18U6aQMS9gw6ah z#xb-k8XB!qjascZmt$ziKD9t9m@z-aJTVA9$6)XX{CyX`*f`&Ra*pw##AGNz0Y1oz z?o+#_CV?2vAV|S?%AzBVAVx92G!B?LFL zA=^)|w7hR&admEfd2(i9h$%~hL;WM8ePg4{zHW)f@=J>H3iFwPGCDQ_wZI~r$l!^d zCK@ff1XYz-yQmSs6eAd_iaxQphgg9u25rdNrIJ3}_}66@=nHnSByznQ9zur)hi*hGc~J;(8M5ybW-#{%#GE@ zWa-MQI8=E~WHnhAJdVkD^)${mKyAKdzHv}S9K*_$a17Itcj8DQbVvgJs`6(fGu>mna zj2pkQKEO8Pf|9CR=85wRUuYGRq`<$Bft`4k==C(figk&qV6ZZ2hwrC05Ri(J%imzm_{1}BOeS9 zgG&Y(HQub$i{~btU>I+lA>y?aIA$2zn;D}MIG>RDu`!?+dal}Aic1E6%x;`A+nkG0 z0fM2!lo)p-9K%04J&LhpJQb~9Nl!UFA$g{$S<%pFfV4hZCC!sy9D}W*YYBgh&oROj zLm8i7By-63#P|^N2XTzE|4$Y$`~-kNOn^+jAZ_DFM@`umkU0uW5d6%f8_=ka3C>VA zQwU#BQ&6#X1(c?A1WQy+w5!u81x<(tU;<@q_%O2Dz4tOxuX!B-f8lsH3bT_y875$l zjt$k;Rbe0D7@mZ(alE5|xz>!2VG%_fGmTC4ZMZ+XI{SwPco`Ezeb1ad3CGmb>=DP* z*OpI?_uRU9=B+nwpFX+o#`SaWKYab+`)|Jfh8rBiay6h2UL5^R<@b|HrEq3LFmlDn z6XVAE1`wmJC8z?9$ppsd{^1;hp9xa&Ii{>U;GuwHI9gm%pba$!M6x-Kp?B9Df)%9(BYnjbqN3EC_O0z_HZ_}@HM_XP{P(`0;m+PZJTcva z1Ig~LwnS`C<=&#w;)ce^z+gWdLz|>QLNfvsc9AK~;6rsbl#znIUFu0Nj!_B3%4@L| zrDAQDOVAbBjj~H4#q6<;nr2AQ&G9RYte`ubd-qhh9y&UjTPEoWs)kini6MPdQR$1g_|qF5&-RwWT6^Kj&+uV69)kIqnbWg&JI%2sLpbirs}hR6h?WY)bh z`Z?(V9dL|$_ZB|YbXO;Xe77+=a>rI^h7KkM$}r}a8Q5%a3=a`W_I&svfvuuu^WiG94M&-UK5Ul#x-u94Zk3i-@sg91KHx`;ti} zDD`y2keQ}LB8Qw6+=ycylW3Nk@=>#s`dLCmV!OVMFPj2_`EMA6t8|eHRpqL6MxB(S zVjVmv4D}!mv4}2^3M&^eb*3CPC5mJGTu;t1AfPt48uDXjDv4KAL&>Ux#Yz;N_zIFk zF>2}?Qp{0Z4nF`qI>fqIE)YN&?(Li$?i=b!31Z}xL561NR2oRRcV@vleZj_?mAV)} z6O7~qR_JVkT^vqj3DOlFFjGTaRatR1`>G4sJ&PNS8G+nB!**Xs<4YVMx$iR`yxi!jAKMO=md_K_16(VFoGD3 zk70%ppz!#9CEwV8t8A2DP$DeYFcvGArU8eM1a*@RDG0WUCWIlkihMKjyC_lV$f)I3 zn4(B0s7xt{mi$vlO>E=?6Q>if)IxCR%UXv4vSnmDS~N46ho+E!@?Y#(@CGFkZN!u`W_y?Y7!VNSak-PMuu2d*{OW zvxhFeaGb8CA3wPN;N917#+*ELj5i^iI(?EK48IVb&v^d$y=f(1AV!`T+%UnkYZuu# zU+0V=1oM?LPL#lv5*`hc)4>F$FjN^#5y~hQ$52jj*=|~iOG6{0y+ebko^GaFclGzeF;%tI zd#fs#Nh^*KwFp6sW`b(E?kcPE6LJjY5XhyxmfdzqA+W1J{X;>wf@_y0-oOTDZx$IP zB2cDoDaA@=7a0YW;470TEFeba5Smgz*);t+kf@+D`Z4M3`pPO(=^>e2m_z49Ca8J{ z=3Eh!sD?ZZ4Q2GB*PlFo{Sx%7^f|_4N>H#<=yY!Pu^gj2DUM;J8$Q+Uo-X_`J9a+L z8;<@i8E)@{%W_3KAF-#`v@9r8K8oYe|+_{q{CPxPO(+kA#wgDFE!}w>MHshfK!=>5DL=phHSQ_IX9aWsGC&5Y<34 zw-9Alfp&J(q-?0fAr(c*Vi%nVh`|{H!LW-0qkZ9+q2WOubPUbl?>{4aArcn$?CtB} zi`E}?o`Lvmp5Oi~uTa@rSqjI{uf!O=bZ;mB^cd%hi=`tOYi(($t*PM01;_ODL|0eF zSk;$tzE>`vy8YtCd#~Pl^;I`RiWO@P9X@!#86RhTL`&&(8kY<`N^--1GIGO+W_*sJ z)3dlF7}uiCpltkjlmSq1CIKiAjBU9bBb{}Q!CE+jk^QHx8uO!9@C~QC8c$8RtZmq# zpu9|(W+ORDft04e927U}cX`#lJ_*mt;^N@&aR10K6Rnfo>F$BP)_AnOF;ZFMrgbsb zi^i!o349EGUhB_>W_J%kxeyfWKC`QPi;$}$HPbOo6{2*>1`WA7QcyZiIs(et zRjiBEp-`+tsL2h(-#f9(W*kFyP=<%8@sL$aC#5pFGZJ*k+%9gT2uAnQeVt27{7vD% z2*`_%k>z^fn7}3T95lo9CHZ4mOuHi<9~~T6n4UOu{K(4u4DYFCW;HLn(ZF6fhT*+f zDXa*9BE$SB3arlo&Q1o-cuL696L0TN#`{tUIb)nBMm9LGzLds>q4E(yyN{kCgFCWn ziZ@iSM4wJb43$Z5lyfWvJ|q!|WH zI9SQPvD}8sAm|XFg90eSHr&sk@Yee3J@{sT9$h{K@?GdlfMf&7>df(E|? zV)1BWQv;A2jkOD5ol#q01<$eVJ9+MH+q1WnDb~zail<`CIACN9 zE70IvVVp*5b5mmkZ%#EMw7NQ5W~O^_#_+00IOh7bvvAD4d$%E;!$?#;%Y$)h)V2AWv@b66MdbJzMW!WWgRCf>M4TFvnOW;Nk zLU(?{jJb&_guDU>bBCCw6l~YNN}ZILl*a@VAQ+0Z*a$`f>2ljxA?zwB#Xk|U)x;O5 zBsb0O9s*w?Uoqbxjv1OUBfnT76_?EO+qOKn^%;7XaLDi8xs#1$o1!hvta^83|7v$K zURId5bIa3JrS7GV*bneU>%<_lVXGtGHXy+$ChnWc)ZTnVQOSUVN?Ir4Yvy6}tIK zf*5rt+2f8Dp+9(fbkK;@zG!PSI{n!o_6Y`#VQ`EH#;C;x#0YE50b}eUlu;~>fnf|^ z0(5ac7^p&?7{d$9`D4IhvqQ4|#trNu=N3hZPNb6(=j!C1!Y>?s1rmiC#xA}fUa|VH zYr)j~6ss_TDTt8p$ABzA4C$nZX0(fci$0y| z_qyDQ%5olkKmfzVL77-GO4riRa6hAiSr3M;B38HJosm_0Sc$QszP5CrFODkY2@^~mc#{`DISulKV{kNJqx~Kw=Z490OfY!G z^%Fh$2BWCY2z)kWHf8CD)Hbw3XgYkMCxs=0g)%EEWW+Kt6REMexn%F2odx+@ckbB5>v4*T%7S%u z=w;)^F_w)UsOc&9!bonb8m$~HSTg-VS4}95UE>&#g+QxTjG#bX1V7RLmmdNS{}8fv z?a{E=tqU%9y_3$$RQ3?WxSJCMiq*ZSN197eWf*^+I^_5{zraX;1Hy$j8AKv^2! zdJ2Wr)m7EieRlVHd)2CH4!NkMjWQKt+WGLpQ7XqokYfl5xQLJil*IJH`VyM4$zaot zazwv3zdiX%YFTRqVl4XH1xgOT{1}Wb9e>;x%N%S=3Vi-B#uy_?M;-Zv*kj@!Qy+=# zr=mwqeSqYS&YMQ=&2S8Msev&jywb*(Fir9^iiB4p1YauCWH>1t6Vpq@h$_H~@B!T) zr7n$dNFtd-8|t=m+I8Fciq#`Vm{YM`IC7e*4W^T+C9};Ul|KR;cBK}f?wTW~1$znF zbP*gh)ukz1IVPJ>MvlT#7u;%xz6LR@G8}#xW5{zXF^n;s zx0s7`gVkhyL?HnYyCQpTiyh)=d|x;_vZfz-)Zy}Z{D?<>;jr@Eu_Jjs7Pu)f979_~ zc}U6iN8eT+?J_Bx9A#3z7Oo`;H8VmqP&h`Kp`{`;foX>8(eVpT7LPsYMDmhl%T7M! z6qkZMW^!_pz0~;AmS(A^;Ag#EA&c8p2pNQ9Y|8I2%e?=fPdKK%C+$?)m?LObsF`FP zcbY;joy~gn2=b-rhO}KVvKBhmq%mmK>a|%yLYgHzP?WvKyF34d|4aY6p%(3Cl%Chj zDr9et6{M)?Av3c#O}U2J@vJPS>Z`5-C~c0h*+!Z6-sEdUNQ1gjyW|Q)&K0W{vs~VD zO7!y(ygDpA^%OsDKlE^n(Ip(y`1^j26PjV+RZCAdHHlBmiANu?_>>cjCDHNGBECNm zj*$~x4kp^VKMUm7v>93|rVc1TP2v~?BNhKej+sLq^(gZ>Mo-#>8C@#k#0Jw&(@v-* z>3oh+Ua|PcXgQuMZ34g|4l1Qn#kM8pU$mo8z{S0$iFJv&Xk~|Rm9&6kf-+%?9Qyxv zj)4V@gm6is!GYB)SFBpLls(3JML6dCb2snXee>@hTTwZu@|op8(-=R=H~3>d}eQdtMkpq7FxU--Oe zq6Wu+@&K19=ZlAf7^7xR%@bZ`%`fZ6P#F1%OQSrh;%w^@@|?}8W(cX`exVp^Jf!YX z=Hd%G@uCaL0Fe6)pPasY*}}!ATLG_kXmEDp28%b1PfoI53DeWlZcgywwcE?LU^B1a zG6gsy4K7HVyppNd{E&*t@4Ux%aYjY`p(b@wswsh-6C?=Ew0+{aEV(jvrHoV=sp=XO z2vz$=us4SwsP5wDC~3boo0fA#W$5_&XKHujSIB9qT_A@`e*SRvq>||n32lOzlT&v^ z@O*SShWuPhXCyPm7&H@5Kfhxw-l7s~Df(#^v|3mNi&>>cSxW7;&6qYU*d9qL^o4)<|JsfL+y!P8YoEFJEezAC;{ zfvHJTb!cpkFwwhmvTqfL`4t=!i18z-v#IBdF6n^7DF$2^S9~eG(hNivLoIVsK;tjM z3YY>&NDI1=pO8cF|8?~&Ftg~C6OQvwmqgAV1g`hi-{}^%1GH@VxEy1j){Maw1#-g*o=TMa7Jh&oRQ5+ z17VK3*%s*a1evw21_LNkO(nEBrZ$*j?FK(dt_`LD>=1J3${$tecBtl;v(ftT9t>sj6S$DHg_7|WL|*syl|wwtf}>T54vcJcXry(^b3 zJT;LoGEjJ)(9gYDql&h|idf;rAQ)IJ!ey>`Pr1x zE4gi0A=(_HV%-&8E{9$!s;QwFdjZJCGtU^En(P@GTs6=?J~MsRIorL+yER=eUPWAe z(Wu+iU0MUx)#eqO!3AkYt2NGU&5QcS5*VZrW!(1C1WhHA5O&GwM0UQqT|@f{MAzmz zD4>?$q{vd$(ZIAS0=6P`&oz7-`y1 zY8T)L&B%$XM?0lli!SV4(SeDEW2*f|#hhbM07EDoIr)`iCVN*_hzZBcIj{C+Sfr*o zv{a5_#Yq9S)h!~*kcHhZPpxu?y(3O=uE!Grw2+5%9J*n#eaQN62yp9 z0$V**5k29Bcyx5sIJ@8(=LzO{;(_Dw;*M}965QRnS=^^?E@}JLi*IkGnQ+YffuuPG zm~f2DfD5%MN2nYFS!4=wBGfcA6O@q(G24I-=n!0h4izH^ZPcg*QU=PT1%i^~*RAaRCH9 zNNxE8vA!S-5W^$TI_3yQWRUg*_G8GZ6ZYbmWgNzP*lkX?ysy!vTX)=a`)xZ0`}-L9 zOzb!3$tS(cq`Tpo%fIq!;g}U>Yp-68V3>SPU9`~973)i1Umq<@hzw|YdU|{?(k~FZ zU>E~QLVlSbJ0?RIgH*&exP)E&l4Z{07(i2y#WUQa8^JX8n8OLp=4WwC>@m%Qz2wJW zb7+pCgrbJs25tr+H-mh)gfv2KkEBYvf80fCR+P!E+LT)>_f?x?%3XKig}`NI{koxM z-t`85jkC_a`r7NP`8zT^x_sFRYsrs~O&C<#S_q`GhOc7@{%j?yxq;JLM@diY@+bco z!ZaJf7iCgQF+o%ElaqdGjUYIEC*mw}BF*(Un6xi~0%{4lVzqoS=cLNW(G3Fi?DRGZ+BphtbmZFJi-!c3ko}QyGjbDz;BwWt9_}8N#RI+VpgGI4I#2! z3Cia>9ORfwF2gPbUmA`{8mmn0HjXJnOU+-?EJ3$xu{VCBp z?Ok51DPHbllJQPV19>gxD}!tpX=w2%zhdOb5X{QchZ~eZGySVhqkW_$HlHv|3l=!> z9i>VJRmru5G&{a}<=CnfBP$BZM4M8pZKF#F25>lf6mTIJv1N=2!32Fu$?mRnKq^Pa z&_l7uG$t9FZF`IYIn(q|$#6_s&{dq_=$He?#Euf0v8z^TpIyxi#FW;WmG}cO;TY{q zt?rB~mG+x&4^ii-k~Hm^pf<$h&^jzr#4f(lb@91pv&sZbDz(h#n7H@) z8b+pSE8tj+LsN}OMz{SeT@c@6!ZE(JR6e)VXa#!Wh$D`mBv|$7wq{tVj4S2w6V0huO* zV=A)DVT*Qt@FF?nG(`y6WHV_UR|<&KMi5Dr=LmC-+pZXn39r;t^~yJuOCSgq!6l)S z3MfUm^UiylU0P7F)~zU`OoAK@DxjomNOxgYek%UrFrv4whpX>`Q%=UUTx94>A1K(m z&Bt&{z!vOwmTy5JI7VcQ;Wy(u1|}lid0_wAH8YDAoNQdl_v4skEIWSnWf#Bj?33r8 zb2h}8niwA*8PY6L5qwh#zN~Bln(@CB$5=?lFVJvO+ZcneE5{H7IW;6FDc12b{(KV- zPbgec2&OER#1eD(;iW)hPA_k#X6O~qzh=y}NQ1H>d6rTKA ztO`*l8gbh|0XGue7>3~k!DnNw#d#Ib~iKsp>#=|rY(*kpI{w=bhmO-K$=0ljs0 zsiLqT(=LK$^B~BHOLe$;4wNLPpt_Jf#IIU51t#D_(~wb45W6l=0{Dhr8s`i>;Tyo83q% zlMHyz@7@QnEyCf0W`=|<%i*)h_+xPO5=w|(r!8WYS$M+H6cUsH2go2pHUJ{A%`qK_ zna44{Q4pTcrWk$PPU&X)X`*Kplo?&Q9Lf}vK!Xd1+2V@CT~U&?4sVyV@)y2Pf1Hp;}d;aC%W%bm!a zIEQ1h_HJdD5R4STh=3!qRGE6p0MS{?badddW!-cPFfqy0;Ut-n<06A~Z2G-vN{)(J z&;d)%gs4jU%~zRxQIel;;}KcjVxtx454LJv3!ZXRSDt2Wgxm}DA(q>uK4jcw^En2) z{O@s0Y%pjh#1oFm;87h*sstk^a>Wa@5h#%cASzYN;fb10NUeqe_Nj=1Sa3=4GcfMM;zD3M;f-r$Jd>_D${1tfhihC3$}BqVl*JYzVs&1(Hu%rssxWoh-Y#U}q-k=!~Ix7~8X_OrLFo0(p}c6MfJ(o874V*CiNKpCmu z8=%nv?Pr%96R>tXmGb)xte|ayohE@?nTDVYnhDT!nC6JX8|%wq@W$ShcOnL! zq&Pl?oWRXthm{Ye3UfIodMFyv{ebk{9yA2CP5DtyQGtY%aeEMC(#P%`fsz(-^VBkO z$Wq0GT0k*s9Ljiu*mnMTThBXJ3TQT;eHM?I4MqefCRX+IxN5HB%+wT6(km@EkS>u0 z@Bu;eGdNN+<;ZUbH+)VfEu^HgBgnT`2+9Ogq&fF=*eU3+L+3#DwofxBTT|Dh%5wy@ zYEIVeX-)M@6_(s(`7oW4zeqs|}noNavBc(8*Q!>H26 z5$s3?Po8MY7BB5vxoTi_caX(sOT1YdnqiwU-XtgEO;VAv#~e5YPly>^k`ArnY7z& zx&&m|Z+Aw`_QztlA>h!WxMj zj!BxF$^I4M)WFKA!6Jvg6=Le@y=CpYhG2p(>nBFUjZpSCd4dV$nO2^XThBd@<5+n} zx;65&$(`Q5wcU5_!TBZ`H)%D=#L&`CQH#-{YO2XDnF1Ng0E^&71()E9O}i4pB4G|n zS_pg)=CDY1NfplCPz&v@iktw1O%-hlIXYT$tkgYmpLM}G+t1j%Y14)cYuBt98XCeeOO`D^jZ^WGrOQqAwzf{9{=@L7T9{RbW5aP)u9v^?=v0psq=%c=P+|kFLc$|;AL!RTs$k{yJnt8_@ zr=BX@ZB$WFTyUaRPvR9I68!8B#*-FwzIROx_&DHS*REebIX%6)w-@yB zj{ZB2` zbwGaiEdN#i*Q-isEAm{lG@Zv#EkKa3OWB*=N^61IPW|KBH7D3rbK1rHp(}sj41^&^ zXqTxn!7k-1h!6_JbTOr%N&_o$Vvk9hD%llTXVR>+cFc+A`a9EHkoH-V{k{B+Jh&|( z<9;@Ck0nNAd&DvLo!QgOz?I8Z_*A5M*Hr;W!Bg$v!{-QaOz_1kvPgzCIELXQR1yD} z{^g5`&_x*>)4OC5l)*9m%ZkIzZ^|)+JR0LiP^L4I)p)}o7$`Hgyl~8PPq8Ib0;oVR zpEhtz3uQXkMCn3`Hq*2TqsYGr$0%P3rV7#PIwl$)5sR&*I|!u;Io(c~*g}FJbGW1f zC<7}e2bNC`6pj&%D}55jbjr8pPFKo7Fok0VJ8`0a8I%#jF_~Z1<{0>*OTiau2&Sgi z2NKJA&Bm}ARx2mSW;U?87?W6T!Z8yAp_!yH&#=BgnQ)90$HWZd%5*rUd^g)LR%a<; z9K+y`W0o#i#1Vpeuo{I|R1gErts}tq(mdE0V?4e(PqTBjK^gY~j;YTmH;#~7)$LjD z?%a~~?V<{mV*)5i=O9ZqLge5`ctUD#@>5Kz zx>T{`$A*z&b~&yCIkZ%Pw2(HHv6&p`pknG)p|S;`guVMa__FUnn`7+3Gw?-(DROd0V$_*|ce5Y^>N_makm8 zdsSn63hfYhEu5i?4%OZPvW2n_DRylm%YDeoyx_VWQ{uKWhKkjHC znj=b)Ky%<2I5sjeLZG%~QdiQdW84_Dh!BA~5mXeCUsbHlH157qrjmgIDr134GX&J& zwStqcMSiUw$iv7bW6N^6HgDYMUe$i?&maXfVMmd+p@b|)sQ3~=D%0LtfS{e)6v4^r zp+gky*y^q0%CT3OoT>B5IsR)>SI@2bJm?7 zmAB9H`RY$#bkp~9am@0G!4+cT5K}yU5W}IlrYkHInCa=qY!m?Ilw3^b=6Mu&$@W5F>V zfSzpiQRW%t0hNcOdxZbHAy<(DnY+v#?RHCW8&-CS;3g&1iA#rMmt-c*^lWlahUp~? z5r~mSNIsp7Ehy|7!XlxN$b}!85KV7W;p8N(#Rxcnnhy{t7J|t^9n0QSQ9vNeNv6hy z)RjiCD@ka%o@xdYZ(mEun6<>8=9C2|SVG3o(n-gD zQF_&-7u|Txl~?){0R_8#+gWF9VUj^k{r&wsVi;ra12>QUKD`()#sv>pIs`(=8W>QL zzQ#IKwh-b0UIOC{#~QxL3KaS&|7otIYSo<5%3#07IWN~#PC3j-p%Ig_bjgJ9F=2c( zIpsT%e%XH0QYwVn5M;Us+!$^Wjzt7_1+AG~O_9#1N0faOd{97+5S`jqv})N58RQ;| zatg;(nu!1tEOj@%W({kQP7CEiEMIP0XVQqHF}+*;`qseU87W96*ug;;5b+n^EVv)Y6oxIzE4?_TgO2gj8vlta93E*V1h0fiUOj z`8}jAIh$IjId~sh>rJthnk-x@>$fYhz(|JURg=AQu27+2hw zWL7ORu7m(IH7CxejYHaFKumhY`v=Ojd(xGE1CDXgT*DGw%*L-Jt}RF<98-pDy7n0D z7sP2?USv)+01=E(3`yXI$`e)SfI{C2}|!qJQmV`Jhrpl!`HC zdTi75_?9)3XUtBWy?zajF~7;|IU`CS2Jv8^sgdG{BeMG77#76ETrrP7j>f_SxtM1X_V0xqqUCWb(4ZC^~nf<3OFuHWb z#TQ(6+2JTz>WCmtA_{1zWeA;WvgS3Yzrw5Bn1D@F=HM_64e0n3`U6hDoUoH-~%Gbx{@(q@#CyG@KqM%w0>^3kQ~ z>4}L6*Adw9JN9xZ9!q1E`rmk-FE04 zJ*O$(N&RmJ%2;q!+ZR@A$qX?>qo)kH@`N%uZk|>LpIJ@OTDL9OlUlW~7D5k%{5jf( z&OxQ^<7P9jbU_(dl6Sbg#z})R;TW4jP)12r66U~+Og%|(xEv)y?OVIs$&};Ik-tvy z1~~s*pR@OMH0;8xD&iQQ>Tts|Wismx^z|~-b7Els7mG4(9C9rllP^Tlxb%I}qIxOd zRV&67?iJUzP$IIpS~Bngc1XmMi1ZiG>J343F0)#w#V)EgVx=p<4wsl<}JW z)zjVBA(gISW6ox`STibwJetuK2X&N#V@3@v6*h|Trr2+anWU4GmSx7zrfb)Ub*DHH z_xUPT$H}JJU_vMDbato@yR2!bMcTyGGXtyE46YU@dzX)_T0GLbWVCOo$f0L)Xywcp z*WJGLQ-kZKKDLrCaN!f<E6tLh>b-UKo3fd#&Dm?VB{W zYSKEcR1Ga{j)6G8nq#7UE6qf}F(4zTQE3Bn$O$({L55w-Dnd5xCChJ@X>X=j_R3HD z(v%4_M9yAm2&wK;xRz)9ke?j*BBoZ3LKfhQxM%NfasL4*Q=-9|JMY?m&%Jk6jwyzj zyY5PZQZk4!>6(m|3NRhm#}X5QVIUD%Ldp^^yLa4r`z;q-a{ifH&q4!~AghDFIF#`| z=26BU#k-jq*PKys%!wx*=b`5VkZWeAieBHm*}x*tl{^CtEwRCX7={@@<3mN`lf&0s zcLkIg8y#G}cwtP)Am_3RwqJAEg*RM%h0o6cnyat4MZ8ux`yd@Ulia3t#vnTO)Ym`VE^mit9IRXh-?>CX(AR zwd5$T;zp5-N%oDeC(C;vhz~*rY0GII=WqgCHmqjV=ue%;%Vt)CeJ} zC^wkK1&mNIp&42V$GHF4V>rUB+pvK*K8|tqSe^`<86k7WI;a`~&Jf(d-bjKY*(`W+ z)*Zc7CpZa@ssm z3p=zfr2{gRtc8_t2M4lC8HH0lCFLhme$8>*cHO$EFgcGxsb7n<+FgPyl~+6^>%+04 zOx>%ZkVh&(Q(6{sL8LlR`&N6HGnMA7{UH*{U+|o58#k?U(_$CKn7oc0f5I{07=udT zm_Us0^U)tT#t;d6jJ18;$+Ujun4++mQdX@fz9wB2Zf`h-JqE}4IJS!HF~=YAxs{7f zF|LFXiov6a_``URMvS3EorfNhrcG%rkep19svMJC(sfqu@n@IP-xVCD2+12l)?80=D9h8vW@8KN;D2A;G7Vk*ZJWa&l(^9ivB z!K@qV5djU847VFos}i~L;Ft}Q{Trr-)=v(Zmn5>ph~bz`vy&huD0A*vn;;7_p2c z-St;||NIZsn5V1k;3Ln?N+2R9s7zoDO9SFrizoZKp3j)zA{0h<%QB zGg4z!UnrBWEUjG4OP6cP0=DXrv4N|uxeRh`*|P4mQ%*3d9#8WtE;{$dt1r9h+N*B9 z?&@2vzov{aU3v*$8Ri3nL`H=uVoX!Ub;c)f418f@5o2uOW{hAqY}&kW^A>T_mNPbO zk#4~pfTqC5=FMa|_=Dfbmb1<(YccwtRZJJeIr+_k<;uvm}9feF71j6 z&u`zMonumcm=kge^#t33U3G6Rg*2?-;>@`|^`b?W+Z5V=rrL7tK)Z2;HJHZhA!O$A zHXS*LGVOeFLjLa3b_ben9^@G0kuFsn@mLgWrh3pMtRpkQrT|~0ib>^XGhIyw(*Jr{ z^x2u_*AgMJG(S0itjsy=>0QZo>fUBk1vG|)JqtLDjSLNz*w|xeUmQc}=KY=)S$xuQ zJ&Oy+M8``zgwfbGA_sA-%*MCZ00)#Y8s$?>$Fbjj_IFM>=BQPtoq|FjNSPpwAz(+D z@w6fwqmf_1F%?i$FD*2+LJv}7F`}kwF$EH3R*tFV8xScIb2zjb4(r6`?Ak3f#X1(9 z)GdQPU79hHmBFlo9cVZvP?C|ISYnbUr`laA%D|U{v3o8K6jJH1NO!Y~FV$?*a7^52 znq}zXJJKPKmc@n91;?O@>Hd{zWX8~sW#tA}iNFQQnDiu$53Lk&OmSzitBF%Xt7nE* zuNm$MxU3r)5H}2$7&+HRv+`D$TSFMbE;Up%Rv4N$N!zOUAvJo;$(TGpB)2*oV-g(F#I3^0*7%CI^cTJrujG(5-;gtGHU zH0;7f#&l&5KvS03V|>Bulv7VMYYEL=LQy2!w#mt^DB7x%2vzk)P`zrV_AdE2MpI5C zD8nS+Fhm-G|c| z%@Tr8I;qc2$|>Y5>WODp`;5pk6H=>QmgswzH@Hx1DIhcXxpdN~d6~5sAxD>L-)7Qw z^$G{s+v!JBxZO_jRTSi>R_#@-B}bn_9)zZkW#t&p!TMyhnTj<{0cF}D)s;zW$~bgA zyPUhU=~21Pu5iK}j`VAh@2_K2STs(|@y+L6^A!(FV}fFbV}^@=3{GjH#eN32{`0Z1dM6<~^N zhEyg=+3e&uM1oY9F+wfUiZaQWV<`#2RHkX4QBbCGOeLF-qYS^`V$jko&y}p>QkHUQ zEGV2*O7&*sC=fF{uu9ZIAf^lkHGncTTu`QR%)~J3j`67u$AFm1F>Co54EKjuHjNI6 z8^-2FdzC3DGt#$yw13@L|AeOC(ZF&8Ov62k%@toWvTE&EZ#X7q82C~J1Y>jw#AJ-g zuqFdcGp)(znL6W2nd1#*_%WEodhBt>_~e|S1frrA>#_HFO25QA5Q0x!20+e|`aDU~lLX@r^+OG&BL6tmf-j`Dxoj$*R_N_S#& zF^?GWxzk*u;&U60fiHqR3WFF&5kfPXQV_~yM2X8wLojz2i%XYd7-NDmcA*oaOZEn0 zm|+4jQa~fqA5{lh<%Zz8g$AQfYYUuc}WK}<2q9Cr-3 z;UeRiM#eGuB%~!k`OI=sfeRksMwb-()Te*PlhCMB|Dc&Y%Mc82U-8VdH{E?Nqtxv~ z{mc3JaV_Vce%S?Euf6<&o3FiM#|>BCdgC=Bs|=L6VEeXB>()*%#0(F46=dmQ*hVv! z%PU?laAtb4c(AOSHSA+FY0IXKj56J{jB^3*f;gLs+z?ISm-5r~kDi4x7Nl-+>Rx=) zmQ%8(MK$|J={GGDj-e`O6zU{Og2rm@fb*ivva4zrnQgt2l2kigf&&EAl@TIDGgWPr zUD>MuEYRi~bI8k%w4+`5kCpad+UWc7Dz&a2$pm?I%& zQY^AmD3_s2KLHwPdsp47oyY_SO`n4fxoAn{B-5!0&L!8Xp07*=>Nyfz8CPC#ofS^4 zS|C?1`F0VMR3*jIT64@!B1cd?6_pff<7qZ!QcRAX*FM+d5^|ta*IEuxo6UnypTUQa zXJRsK$``bd4%Y&CR!U2qrdZl1%Tz^qA>ANoA&uy*4%AES`sc4u^Zi=NpXS`{-aZZ2 zdNuJDVnoTK!EH>o#DcG*4Gk9m7!X7ChGUpyC`FEzD^5L`UrPmuIh2r15Ks`O8I8*1 zZBw;9chd)BfYW5tRL#%I5H@*$3*B_VuscZ z56%t^WbBFC@7j@pHJo$HqAzB^aS|`zQUEj{W_Gk^cC6nNYmU8}XNnny4JN5&e+?~( zI7Vjtw3=y6gYonAvn;c_hx+|uEfr6B86L$ki&lUvNY^MW^rkcF1773DHD@SI0nkZ9uu0Wyiz%aRVKUI z9CKUa_FJhXIFikF+TcWIijy+HA|*o@QiYRGPT}kVA3`$OU|3>6isfMT-g$@BS?;*^ zo&)#Xot)4NGf99(t)L76*>J)&kc3?_?FgnY#>5^2Rx*~blVXmcxuZ;e94fAnC zlkL5|e=Hn(G<;!e;dCp-G0o8Vaf~iz1K}9v4Ub1}`xbODv}7;D>Fr-RFx0bT`ND;# zogf_<@4Mx;>+Za3*V;9stCpYIw|cQpEM0!#wyQ2Nv~@yYVW9nVYY_$~>m+ zXKuE@%;-?x_{hM>aQ~PWLbuiUFb|uViSae2e9ug;ot@e+yJr2mnN1wn*RPQldEHu$ zE}OZ{5Y_^nb!TiWpmXM?0y<}H-o*cA>lq+s3%Q-&mJL0n{3oS_VX@nvs|t*sqiL#wjF85q2@cn;t9+QC)`|{G8GXYV}MVV|$Jp>cT*{m(d_qc2aIVqO3R;-81DWvl<^~$NGt5Vn74^^6T zmy%srOUQU|v(R#RX_82jr>2OE5Wg3XN zuyTxXrOU4kC23JOfJb3W(viTTCq0foUdJ%QSdo^S=9;UhaC}!Fy|t0&#^YmKfyn=%Y`3`O9B^ z>gg{%`P7%b^d(4Ryh;1!!yEF>T!a%$JnC|c5hY(%Dc@H?HQg0&39K?DSkU>4N7-eG z6~ji&y1j=RK=;Js|2yj21#8z+h@Oh3F8k1u_C5W~TH+$JY~`Y*D^6X!?35L&PrvNS z3+}#W&-v$`v0~{d;i+KEQu{1z=1N7J& z>K$Mr9UX)+;>_fzxMoTmo1Gq8J2Sp+cB~WEOss37%#zO}xpr#fy6H{p;ZBL0nIw&| zuAh-e*_Iwq

LhY>VYxv*ZgG*HkX= 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͙ZI;K^UO2PBBN)Yw_)%I34P;@H;~ekPd*7{ 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�yH{`BK6~ln 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

hKSdkh@Ika!46+zZK$mS0vRRjSM>?plfa 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 From 8b52a4c0c5c64f6aa351d030253ae2427215d545 Mon Sep 17 00:00:00 2001 From: Dmitry Pigasin Date: Thu, 8 Jul 2021 17:10:00 +0300 Subject: [PATCH 12/13] Remove sudo from mo install_prerequisites.sh (#6378) * Remove sudo from mo install_prerequisites.sh * Move venv folder to $HOME dir * Wrap $venv_python_binary with double quotes * Add variable to store `$HOME/venv_mo` * Use one venv for all OpenVINO tools * Add ROOT_DIR variable * Add python venv creation * Add message about venv to the .bat script * Fix a typo --- .../install_prerequisites.bat | 49 +++++++++++++++---- .../install_prerequisites.sh | 42 ++++++---------- 2 files changed, 53 insertions(+), 38 deletions(-) diff --git a/model-optimizer/install_prerequisites/install_prerequisites.bat b/model-optimizer/install_prerequisites/install_prerequisites.bat index ac756ad4905..7d2aca04fc9 100644 --- a/model-optimizer/install_prerequisites/install_prerequisites.bat +++ b/model-optimizer/install_prerequisites/install_prerequisites.bat @@ -6,6 +6,8 @@ :: Check if Python is installed setlocal +set ROOT_DIR=%~dp0 + python --version 2>NUL if errorlevel 1 ( echo Error^: Python is not installed. Please install Python 3.5 ^(64-bit^) or higher from https://www.python.org/downloads/ @@ -35,10 +37,16 @@ if not "%python_ver%"=="okay" ( :: install Python modules +set USE_VENV="false" +set VENV_DIR=%USERPROFILE%\Documents\Intel\OpenVINO\venv_openvino IF /I "%1%" EQU "" ( set postfix= ) ELSE ( + IF /I "%1%" EQU "venv" ( + set postfix= + set USE_VENV="true" + ) ELSE ( IF /I "%1%" EQU "caffe" ( set postfix=_caffe ) ELSE ( @@ -59,6 +67,7 @@ IF /I "%1%" EQU "" ( ) ELSE ( echo Unsupported framework goto error + ) ) ) ) @@ -67,10 +76,20 @@ IF /I "%1%" EQU "" ( ) ) -pip3 install --user -r ..\requirements%postfix%.txt +IF /I "%2%" EQU "venv" ( + set USE_VENV="true" +) + +IF %USE_VENV% == "true" ( + python -m venv "%VENV_DIR%" + call "%VENV_DIR%\Scripts\activate.bat" +) + +python -m pip install -U pip +python -m pip install -r "%ROOT_DIR%..\requirements%postfix%.txt" :: Chek MO version -set python_command='python "%~dp0..\mo\utils\extract_release_version.py"' +set python_command='python "%ROOT_DIR%..\mo\utils\extract_release_version.py"' FOR /F "delims=" %%i IN (%python_command%) DO set mo_release_version=%%i IF "%mo_release_version%" == "None.None" ( set mo_is_custom="true" @@ -80,12 +99,12 @@ IF "%mo_release_version%" == "None.None" ( :: Check if existing IE Python bindings satisfy requirements set errorlevel= -python "%~dp0..\mo\utils\find_ie_version.py" +python "%ROOT_DIR%..\mo\utils\find_ie_version.py" IF %errorlevel% EQU 0 goto ie_search_end :: Check if OV already installed via pip set errorlevel= -pip3 show openvino +python -m pip show openvino IF %errorlevel% EQU 0 ( IF %mo_is_custom% == "true" ( echo [ WARNING ] OpenVINO ^(TM^) Toolkit version installed in pip is incompatible with the Model Optimizer @@ -110,7 +129,7 @@ IF %mo_is_custom% == "true" ( ) set errorlevel= -pip3 install openvino==%mo_release_version% +python -m pip install openvino==%mo_release_version% IF %errorlevel% NEQ 0 ( echo [ WARNING ] Could not find the OpenVINO ^(TM^) toolkit version %mo_release_version% in pip echo [ WARNING ] The highest OpenVINO ^(TM^) toolkit version will be installed ^(may be incompatible with current Model Optimizer version^) @@ -119,17 +138,17 @@ IF %errorlevel% NEQ 0 ( ) set errorlevel= -python "%~dp0..\mo\utils\find_ie_version.py" +python "%ROOT_DIR%..\mo\utils\find_ie_version.py" IF %errorlevel% EQU 0 goto ie_search_end echo [ WARNING ] The installed OpenVINO ^(TM^) toolkit version %mo_release_version% does not work as expected. Uninstalling... -pip3 uninstall -y openvino +python -m pip uninstall -y openvino echo [ WARNING ] Consider building the Inference Engine Python API from sources goto ie_search_end :install_last_ov set errorlevel= -pip3 install openvino +python -m pip install openvino IF %errorlevel% NEQ 0 ( echo [ WARNING ] Could not find OpenVINO ^(TM^) toolkit version available in pip for installation echo [ WARNING ] Consider building the Inference Engine Python API from sources @@ -137,16 +156,26 @@ IF %errorlevel% NEQ 0 ( ) set errorlevel= -python "%~dp0..\mo\utils\find_ie_version.py" +python "%ROOT_DIR%..\mo\utils\find_ie_version.py" IF %errorlevel% EQU 0 goto ie_search_end echo [ WARNING ] The installed highest OpenVINO ^(TM^) toolkit version doesn't work as expected. Uninstalling... -pip3 uninstall -y openvino +python -m pip uninstall -y openvino echo [ WARNING ] Consider building the Inference Engine Python API from sources goto ie_search_end :ie_search_end +IF %USE_VENV% == "true" ( + echo. + echo Before running the Model Optimizer, please activate virtualenv environment by running "%VENV_DIR%\Scripts\activate.bat" +) ELSE ( + echo. + echo [ WARNING ] All Model Optimizer dependencies are installed globally. + echo [ WARNING ] If you want to keep Model Optimizer in separate sandbox + echo [ WARNING ] run install_prerequisites.bat "{caffe|tf|tf2|mxnet|kaldi|onnx}" venv +) + echo ***************************************************************************************** echo Optional: To speed up model conversion process, install protobuf-*.egg located in the echo "model-optimizer\install_prerequisites" folder or building protobuf library from sources. diff --git a/model-optimizer/install_prerequisites/install_prerequisites.sh b/model-optimizer/install_prerequisites/install_prerequisites.sh index bd2deb23ae5..17c26201cf1 100755 --- a/model-optimizer/install_prerequisites/install_prerequisites.sh +++ b/model-optimizer/install_prerequisites/install_prerequisites.sh @@ -35,6 +35,7 @@ for ((i=1;i <= $#;i++)) { esac } +VENV_DIR="$HOME/venv_openvino" SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]-$0}" )" && pwd )" if [[ -f /etc/centos-release ]]; then @@ -53,23 +54,8 @@ if [[ $DISTRO == "centos" ]]; then elif command -v python3.5 >/dev/null 2>&1; then python_binary=python3.5 fi - - if [ -z "$python_binary" ]; then - sudo -E yum install -y https://centos7.iuscommunity.org/ius-release.rpm - sudo -E yum install -y python36u python36u-pip - sudo -E pip3.6 install virtualenv - python_binary=python3.6 - fi - # latest pip is needed to install tensorflow - sudo -E "$python_binary" -m pip install --upgrade pip -elif [[ $DISTRO == "ubuntu" ]]; then - sudo -E apt update - sudo -E apt -y --no-install-recommends install python3-pip python3-venv +else python_binary=python3 - sudo -E "$python_binary" -m pip install --upgrade pip -elif [[ "$OSTYPE" == "darwin"* ]]; then - python_binary=python3 - python3 -m pip install --upgrade pip fi install_latest_ov() { @@ -181,21 +167,21 @@ find_ie_bindings() { } if [[ $V_ENV -eq 1 ]]; then - "$python_binary" -m venv "$SCRIPTDIR/../venv${postfix}" - source "$SCRIPTDIR/../venv${postfix}/bin/activate" - venv_python_binary="$SCRIPTDIR/../venv${postfix}/bin/$python_binary" - $venv_python_binary -m pip install -r "$SCRIPTDIR/../requirements${postfix}.txt" + "$python_binary" -m venv "$VENV_DIR" + source "$VENV_DIR/bin/activate" + venv_python_binary="$VENV_DIR/bin/$python_binary" + # latest pip is needed to install tensorflow + "$venv_python_binary" -m pip install --upgrade pip + "$venv_python_binary" -m pip install -r "$SCRIPTDIR/../requirements${postfix}.txt" find_ie_bindings "$venv_python_binary" false echo - echo "Before running the Model Optimizer, please activate virtualenv environment by running \"source ${SCRIPTDIR}/../venv${postfix}/bin/activate\"" + echo "Before running the Model Optimizer, please activate virtualenv environment by running \"source $VENV_DIR/bin/activate\"" else - if [[ "$OSTYPE" == "darwin"* ]]; then - python3 -m pip install -r "$SCRIPTDIR/../requirements${postfix}.txt" - find_ie_bindings python3 false - else - sudo -E $python_binary -m pip install -r "$SCRIPTDIR/../requirements${postfix}.txt" - find_ie_bindings $python_binary true - fi + # latest pip is needed to install tensorflow + "$python_binary" -m pip install --upgrade pip + "$python_binary" -m pip install -r "$SCRIPTDIR/../requirements${postfix}.txt" + find_ie_bindings "$python_binary" false + echo echo "[WARNING] All Model Optimizer dependencies are installed globally." echo "[WARNING] If you want to keep Model Optimizer in separate sandbox" echo "[WARNING] run install_prerequisites.sh \"{caffe|tf|tf2|mxnet|kaldi|onnx}\" venv" From 2a970a56d303443041629a1fbd0029a9b8437669 Mon Sep 17 00:00:00 2001 From: Gleb Kazantaev Date: Fri, 9 Jul 2021 00:38:07 +0300 Subject: [PATCH 13/13] Enable common optimizations on MO (#6245) * Enable common optimizations on MO * Added tensor name tracking; updated tests * Disable DilatedConvolution transform * Fix TopK3 transformation * Codestyle fix * Update tensor name logic * Fix scatter nd shape inference for dynamic shape * Update FrameworkNode to propagate dynamic output shape * Enable HSwish in MO that is missing in nGrpah * Cleanup MO and IE code * Fix review comments * Fix unit test --- .../src/moc_transformations.cpp | 44 ++++++- .../include/ngraph_ops/framework_node.hpp | 3 + .../common_optimizations/pad_fusion.hpp | 12 ++ .../src/ngraph_ops/framework_node.cpp | 70 ++++++++--- .../common_optimizations/pad_fusion.cpp | 32 +++++ .../common_optimizations/softplus_fusion.cpp | 18 +-- .../op_conversions/convert_topk3.cpp | 1 + .../transformations/framework_node_test.cpp | 59 +++++++++ .../transformations/pad_fusion.cpp | 46 +++++++ .../common_test_utils/ngraph_test_utils.cpp | 8 ++ .../common_test_utils/ngraph_test_utils.hpp | 4 + model-optimizer/automation/package_BOM.txt | 5 - .../extensions/front/Mish_fusion.py | 48 ------- .../extensions/front/Softplus_fusion.py | 43 ------- .../extensions/front/Swish_fusion.py | 87 ------------- .../front/onnx/quantize_dequantize_linear.py | 87 ------------- .../onnx/remove_filtering_boxes_by_size.py | 117 ----------------- .../extensions/front/Mish_fusion_test.py | 66 ---------- .../extensions/front/Softplus_fusion_test.py | 57 --------- .../extensions/front/Swish_fusion_test.py | 119 ------------------ .../onnx/quantize_dequantize_linear_test.py | 115 ----------------- .../core/include/ngraph/descriptor/tensor.hpp | 1 + ngraph/core/src/descriptor/tensor.cpp | 8 ++ ngraph/core/src/graph_util.cpp | 14 ++- ngraph/core/src/node_output.cpp | 1 + ngraph/core/src/op/util/scatter_nd_base.cpp | 4 +- ngraph/test/replace_node.cpp | 60 +++++++++ 27 files changed, 352 insertions(+), 777 deletions(-) create mode 100644 inference-engine/tests/functional/inference_engine/transformations/framework_node_test.cpp delete mode 100644 model-optimizer/extensions/front/Mish_fusion.py delete mode 100644 model-optimizer/extensions/front/Softplus_fusion.py delete mode 100644 model-optimizer/extensions/front/Swish_fusion.py delete mode 100644 model-optimizer/extensions/front/onnx/quantize_dequantize_linear.py delete mode 100644 model-optimizer/extensions/front/onnx/remove_filtering_boxes_by_size.py delete mode 100644 model-optimizer/unit_tests/extensions/front/Mish_fusion_test.py delete mode 100644 model-optimizer/unit_tests/extensions/front/Softplus_fusion_test.py delete mode 100644 model-optimizer/unit_tests/extensions/front/Swish_fusion_test.py delete mode 100644 model-optimizer/unit_tests/extensions/front/onnx/quantize_dequantize_linear_test.py diff --git a/inference-engine/src/offline_transformations/src/moc_transformations.cpp b/inference-engine/src/offline_transformations/src/moc_transformations.cpp index 745e173b4d7..50ae6bcaa7e 100644 --- a/inference-engine/src/offline_transformations/src/moc_transformations.cpp +++ b/inference-engine/src/offline_transformations/src/moc_transformations.cpp @@ -5,12 +5,54 @@ #include #include "moc_transformations.hpp" -#include "pruning.hpp" #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include NGRAPH_RTTI_DEFINITION(ngraph::pass::MOCTransformations, "MOCTransformations", 0); bool ngraph::pass::MOCTransformations::run_on_function(std::shared_ptr f) { + // To avoid issues with dynamism we make nGraph Function dynamic and after we apply all + // transformations we restore original shapes to the nGraph Function back + std::unordered_map input_shapes; + for (auto && param : f->get_parameters()) { + input_shapes[param.get()] = param->get_partial_shape(); + param->set_partial_shape(PartialShape::dynamic(param->get_partial_shape().rank())); + } + f->validate_nodes_and_infer_types(); + + ngraph::pass::Manager manager(get_pass_config()); + + manager.register_pass(); + manager.register_pass(); + manager.register_pass(); + + auto common_fusions = manager.register_pass(); + common_fusions->add_matcher(); + common_fusions->add_matcher(); + common_fusions->add_matcher(); + common_fusions->add_matcher(); + common_fusions->add_matcher(); + common_fusions->add_matcher(); + common_fusions->add_matcher(); + common_fusions->set_name("ngraph::pass::CommonFusions"); + + manager.run_passes(f); + + // Restore original shapes to the nGraph Function + for (auto && param : f->get_parameters()) { + param->set_partial_shape(input_shapes.at(param.get())); + } + f->validate_nodes_and_infer_types(); + return false; } \ No newline at end of file diff --git a/inference-engine/src/transformations/include/ngraph_ops/framework_node.hpp b/inference-engine/src/transformations/include/ngraph_ops/framework_node.hpp index c19a8500ecc..1a5729d8ecd 100644 --- a/inference-engine/src/transformations/include/ngraph_ops/framework_node.hpp +++ b/inference-engine/src/transformations/include/ngraph_ops/framework_node.hpp @@ -71,8 +71,11 @@ public: std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; + void cache_output_descriptor(); + private: std::vector> m_inputs_desc; + std::vector> m_output_desc; FrameworkNodeAttrs m_attrs; }; diff --git a/inference-engine/src/transformations/include/transformations/common_optimizations/pad_fusion.hpp b/inference-engine/src/transformations/include/transformations/common_optimizations/pad_fusion.hpp index 7c11f1ee02a..37c903de952 100644 --- a/inference-engine/src/transformations/include/transformations/common_optimizations/pad_fusion.hpp +++ b/inference-engine/src/transformations/include/transformations/common_optimizations/pad_fusion.hpp @@ -12,6 +12,7 @@ namespace ngraph { namespace pass { class TRANSFORMATIONS_API PadFusion; +class TRANSFORMATIONS_API PadElimination; class TRANSFORMATIONS_API PadFusionAvgPool; class TRANSFORMATIONS_API PadFusionMaxPool; class TRANSFORMATIONS_API PadFusionConvolution; @@ -22,6 +23,16 @@ class TRANSFORMATIONS_API PadFusionGroupConvolutionBackpropData; } // namespace pass } // namespace ngraph +/** + * @ingroup ie_transformation_common_api + * @brief PadElimination eliminates pad that does nothing + */ +class ngraph::pass::PadElimination: public ngraph::pass::MatcherPass { +public: + NGRAPH_RTTI_DECLARATION; + PadElimination(); +}; + /** * @ingroup ie_transformation_common_api * @brief PadFusion transformation replaces following graph: @@ -113,5 +124,6 @@ public: add_matcher(); add_matcher(); add_matcher(); + add_matcher(); } }; diff --git a/inference-engine/src/transformations/src/ngraph_ops/framework_node.cpp b/inference-engine/src/transformations/src/ngraph_ops/framework_node.cpp index 567c54bf04d..b25143c20f5 100644 --- a/inference-engine/src/transformations/src/ngraph_ops/framework_node.cpp +++ b/inference-engine/src/transformations/src/ngraph_ops/framework_node.cpp @@ -25,31 +25,71 @@ shared_ptr op::FrameworkNode::clone_with_new_inputs(const OutputVector& ne return node; } +void op::FrameworkNode::cache_output_descriptor() { + for (size_t i = 0; i < get_output_size(); ++i) { + m_output_desc.emplace_back(get_output_partial_shape(i), get_output_element_type(i)); + } +} + void op::FrameworkNode::validate_and_infer_types() { INTERNAL_OP_SCOPE(FrameworkNode_validate_and_infer_types); // Save initial inputs descriptors bool initialize_input_desc = m_inputs_desc.empty(); + bool reset_output_shape_to_dynamic = false; + bool reset_output_shape_to_original = false; for (uint64_t i = 0; i < get_input_size(); i++) { // TODO: store constant values - const auto& new_input_desc = - std::make_tuple(get_input_partial_shape(i), get_input_element_type(i)); + const auto& input_pshape = get_input_partial_shape(i); + const auto& input_type = get_input_element_type(i); + const auto& rank = input_pshape.rank(); + + const auto & get_error_message = [&]() { + std::stringstream out; + out << "Input descriptor for " << get_friendly_name() + << " node has been changed:" << std::endl; + out << "Before: " << std::get<0>(m_inputs_desc[i]) << ", " + << std::get<1>(m_inputs_desc[i]) << std::endl; + out << "After: " << input_pshape << ", " + << input_type << std::endl; + out << "Please specify InferenceEngine Extensions to support this case."; + return out.str(); + }; if (initialize_input_desc) { - m_inputs_desc.push_back(new_input_desc); + m_inputs_desc.emplace_back(input_pshape, input_type); } else { - auto get_message = [&]() { - std::stringstream out; - out << "Input descriptor for " << get_friendly_name() - << " node has been changed:" << std::endl; - out << "Before: " << std::get<0>(m_inputs_desc[i]) << ", " - << std::get<1>(m_inputs_desc[i]) << std::endl; - out << "After: " << std::get<0>(new_input_desc) << ", " - << std::get<1>(new_input_desc) << std::endl; - out << "Please specify InferenceEngine Extensions to support this case."; - return out.str(); - }; + const auto& orig_input_pshape = std::get<0>(m_inputs_desc[i]); + if (orig_input_pshape == input_pshape) { + reset_output_shape_to_original = true; + } else if (input_pshape.rank().is_dynamic()) { + reset_output_shape_to_dynamic = true; + } else if (rank.is_static() && orig_input_pshape.rank().is_static() && + rank.get_length() == orig_input_pshape.rank().get_length()) { + for (int64_t dim = 0; dim < rank.get_length(); ++dim) { + NODE_VALIDATION_CHECK(this, input_pshape[dim].is_dynamic() || + (orig_input_pshape[dim].is_static() && + orig_input_pshape[dim].get_length() == input_pshape[dim].get_length()), + get_error_message()); + } + reset_output_shape_to_dynamic = true; + } else { + NODE_VALIDATION_CHECK(this, m_inputs_desc[i] == std::make_tuple(input_pshape, input_type), get_error_message()); + } + } + } - NODE_VALIDATION_CHECK(this, m_inputs_desc[i] == new_input_desc, get_message()); + if (reset_output_shape_to_dynamic) { + cache_output_descriptor(); + for (size_t i = 0; i < get_output_size(); ++i) { + if (get_output_partial_shape(i).rank().is_static()) { + set_output_type(i, get_output_element_type(i), PartialShape::dynamic()); + } + } + } + + if (reset_output_shape_to_original && !m_output_desc.empty()) { + for (size_t i = 0; i < get_output_size(); ++i) { + set_output_type(i, std::get<1>(m_output_desc[i]), std::get<0>(m_output_desc[i])); } } } diff --git a/inference-engine/src/transformations/src/transformations/common_optimizations/pad_fusion.cpp b/inference-engine/src/transformations/src/transformations/common_optimizations/pad_fusion.cpp index c8e53e74c1f..b2655f8797c 100644 --- a/inference-engine/src/transformations/src/transformations/common_optimizations/pad_fusion.cpp +++ b/inference-engine/src/transformations/src/transformations/common_optimizations/pad_fusion.cpp @@ -12,6 +12,7 @@ #include #include #include +#include using namespace ngraph; @@ -385,3 +386,34 @@ pass::PadFusionGroupConvolutionBackpropData::PadFusionGroupConvolutionBackpropDa auto m = std::make_shared(conv_pattern, matcher_name); this->register_matcher(m, callback); } + +NGRAPH_RTTI_DEFINITION(pass::PadElimination, "PadElimination", 0); + +pass::PadElimination::PadElimination() { + MATCHER_SCOPE(PadElimination); + auto pad_node_pattern = pattern::wrap_type(); + + matcher_pass_callback callback = [=](pattern::Matcher& m) { + auto pad = m.get_match_root(); + + auto pad_begin_const = ngraph::get_constant_from_source(pad->input_value(1)); + auto pad_end_const = ngraph::get_constant_from_source(pad->input_value(2)); + + if (!pad_begin_const || !pad_end_const) { + return false; + } + + const auto pad_begin_value = pad_begin_const->cast_vector(); + const auto pad_end_value = pad_end_const->cast_vector(); + + if (std::any_of(pad_begin_value.begin(), pad_begin_value.end(), [](int64_t value) { return value != 0; }) || + std::any_of(pad_end_value.begin(), pad_end_value.end(), [](int64_t value) { return value != 0; })) { + return false; + } + + return replace_output_update_name(pad->output(0), pad->input_value(0)); + }; + + auto m = std::make_shared(pad_node_pattern, matcher_name); + this->register_matcher(m, callback); +} \ No newline at end of file diff --git a/inference-engine/src/transformations/src/transformations/common_optimizations/softplus_fusion.cpp b/inference-engine/src/transformations/src/transformations/common_optimizations/softplus_fusion.cpp index 0c768800eea..c9a19623352 100644 --- a/inference-engine/src/transformations/src/transformations/common_optimizations/softplus_fusion.cpp +++ b/inference-engine/src/transformations/src/transformations/common_optimizations/softplus_fusion.cpp @@ -19,26 +19,20 @@ ngraph::pass::SoftPlusFusion::SoftPlusFusion() { // fuses ln(exp(x) + 1.0) operations into SoftPlus(x) auto input = ngraph::pattern::any_input(); auto exp = std::make_shared(input); - auto add_constant = ngraph::pattern::wrap_type(); + auto add_constant = ngraph::pattern::wrap_type( + pattern::type_matches_any({element::f32, element::f16})); auto add = std::make_shared(exp, add_constant); auto log = std::make_shared(add); ngraph::matcher_pass_callback callback = [=](ngraph::pattern::Matcher &m) { - auto &pattern_to_output = m.get_pattern_value_map(); + const auto &pattern_to_output = m.get_pattern_value_map(); auto exp_input = pattern_to_output.at(input); auto constant = std::dynamic_pointer_cast(pattern_to_output.at(add_constant).get_node_shared_ptr()); + if (!constant) return false; - if (constant == nullptr) { - return false; - } - - if (constant->get_element_type() == ngraph::element::f32 || constant->get_element_type() == ngraph::element::f16) { - auto data = constant->cast_vector(); - if (data.size() != 1 || data[0] != 1.0) { - return false; - } - } else { + auto data = constant->cast_vector(); + if (data.size() != 1 || data[0] != 1.0) { return false; } diff --git a/inference-engine/src/transformations/src/transformations/op_conversions/convert_topk3.cpp b/inference-engine/src/transformations/src/transformations/op_conversions/convert_topk3.cpp index 97d9031bd99..45eba021464 100644 --- a/inference-engine/src/transformations/src/transformations/op_conversions/convert_topk3.cpp +++ b/inference-engine/src/transformations/src/transformations/op_conversions/convert_topk3.cpp @@ -40,6 +40,7 @@ ngraph::pass::ConvertTopK3::ConvertTopK3() { last1 = new_topk->output(1); new_topk->set_friendly_name(topk->get_friendly_name()); } else if (topk->get_output_target_inputs(0).size() == 0) { + last0 = topk->output(0); last1 = std::make_shared(new_topk->output(1), topk->get_index_element_type()); new_ops.push_back(last1.get_node_shared_ptr()); diff --git a/inference-engine/tests/functional/inference_engine/transformations/framework_node_test.cpp b/inference-engine/tests/functional/inference_engine/transformations/framework_node_test.cpp new file mode 100644 index 00000000000..a87bb245856 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/transformations/framework_node_test.cpp @@ -0,0 +1,59 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include +#include +#include + +#include +#include + +#include "common_test_utils/ngraph_test_utils.hpp" + + +using namespace testing; +using namespace ngraph; + + +TEST(TransformationTests, FrameworkNode) { + auto param = std::make_shared(element::i64, Shape{1, 64}); + auto f_node = std::make_shared(OutputVector{param}); + f_node->set_output_type(0, element::i64, Shape{1, 64}); + + // Set partially dynamic shape + param->set_partial_shape(PartialShape{Dimension::dynamic(), 64}); + param->validate_and_infer_types(); + + ASSERT_NO_THROW(f_node->validate_and_infer_types()); + ASSERT_EQ(f_node->get_output_partial_shape(0), PartialShape::dynamic()); + + // Set dynamic shape + param->set_partial_shape(PartialShape::dynamic(2)); + param->validate_and_infer_types(); + + ASSERT_NO_THROW(f_node->validate_and_infer_types()); + ASSERT_EQ(f_node->get_output_partial_shape(0), PartialShape::dynamic()); + + // Set fully dynamic shape + param->set_partial_shape(PartialShape::dynamic()); + param->validate_and_infer_types(); + + ASSERT_NO_THROW(f_node->validate_and_infer_types()); + ASSERT_EQ(f_node->get_output_partial_shape(0), PartialShape::dynamic()); + + // Set original static shape + param->set_partial_shape(Shape{1, 64}); + param->validate_and_infer_types(); + + ASSERT_NO_THROW(f_node->validate_and_infer_types()); + ASSERT_EQ(f_node->get_output_partial_shape(0), PartialShape({1, 64})); + + // Set different static shape + param->set_partial_shape(Shape{2, 64}); + param->validate_and_infer_types(); + + ASSERT_THROW(f_node->validate_and_infer_types(), ngraph_error::exception); +} \ No newline at end of file diff --git a/inference-engine/tests/functional/inference_engine/transformations/pad_fusion.cpp b/inference-engine/tests/functional/inference_engine/transformations/pad_fusion.cpp index ea96555ea01..e3e6bc40081 100644 --- a/inference-engine/tests/functional/inference_engine/transformations/pad_fusion.cpp +++ b/inference-engine/tests/functional/inference_engine/transformations/pad_fusion.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "common_test_utils/ngraph_test_utils.hpp" @@ -21,6 +22,42 @@ using namespace testing; using namespace ngraph; +TEST(TransformationTests, PadElimination) { + std::shared_ptr f(nullptr), f_ref(nullptr); + + Shape data_shape{1, 3, 14, 14}; + { + auto data = std::make_shared(element::i32, data_shape); + set_tensor_name(data, "param"); + auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 0, 0}); + auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 0, 0}); + auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); + set_tensor_name(pad, "pad"); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(pad, filters, Strides{1, 1}, + CoordinateDiff{0, 0}, CoordinateDiff{1, 1}, Shape{1, 1}); + set_tensor_name(conv, "conv"); + f = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + } + { + auto data = std::make_shared(element::i32, data_shape); + set_tensor_names(data, {"param", "pad"}); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(data, filters, Strides{1, 1}, + CoordinateDiff{0, 0}, CoordinateDiff{1, 1}, Shape{1, 1}, + op::PadType::EXPLICIT); + set_tensor_name(conv, "conv"); + f_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} TEST(TransformationTests, PadFusionAvgPoolExcludePad) { std::shared_ptr f(nullptr), f_ref(nullptr); @@ -155,9 +192,11 @@ TEST(TransformationTests, PadFusionConvolutionBackpropData) { auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); + set_tensor_name(pad, "pad"); auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); auto conv = std::make_shared(pad, filters, Strides{1, 1}, CoordinateDiff{4, 4}, CoordinateDiff{3, 3}, Shape{1, 1}); + set_tensor_name(conv, "conv"); f = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); pass::Manager m; @@ -171,6 +210,7 @@ TEST(TransformationTests, PadFusionConvolutionBackpropData) { auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); auto conv = std::make_shared(data, filters, Strides{1, 1}, CoordinateDiff{3, 3}, CoordinateDiff{1, 1}, Shape{1, 1}); + set_tensor_name(conv, "conv"); f_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); } @@ -389,12 +429,15 @@ TEST(TransformationTests, NegativePadFusionConvolutionBackpropDataTooSmallPad) { Shape data_shape{1, 3, 14, 14}; { auto data = std::make_shared(element::f32, data_shape); + set_tensor_name(data, "data"); auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); + set_tensor_name(pad, "pad"); auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); auto conv = std::make_shared(pad, filters, Strides{1, 1}, CoordinateDiff{1, 1}, CoordinateDiff{1, 1}, Shape{1, 1}); + set_tensor_name(conv, "conv"); f = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); pass::Manager m; @@ -405,12 +448,15 @@ TEST(TransformationTests, NegativePadFusionConvolutionBackpropDataTooSmallPad) { } { auto data = std::make_shared(element::f32, data_shape); + set_tensor_name(data, "data"); auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); + set_tensor_name(pad, "pad"); auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); auto conv = std::make_shared(pad, filters, Strides{1, 1}, CoordinateDiff{1, 1}, CoordinateDiff{1, 1}, Shape{1, 1}); + set_tensor_name(conv, "conv"); f_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); } diff --git a/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.cpp b/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.cpp index 3d0ec47531d..1af6642ba87 100644 --- a/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.cpp +++ b/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.cpp @@ -779,6 +779,14 @@ void check_rt_info(const std::shared_ptr& f) { } } +void set_tensor_name(ngraph::Output output, const std::string & name) { + output.get_tensor_ptr()->set_names({name}); +} + +void set_tensor_names(ngraph::Output output, const std::unordered_set & names) { + output.get_tensor_ptr()->set_names(names); +} + NGRAPH_RTTI_DEFINITION(TestOpMultiOut, "TestOp", 0); namespace attributes { diff --git a/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.hpp b/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.hpp index ab636060af1..116226da962 100644 --- a/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.hpp +++ b/inference-engine/tests/ie_test_utils/common_test_utils/ngraph_test_utils.hpp @@ -101,6 +101,10 @@ inline std::pair compare_functions( void check_rt_info(const std::shared_ptr& f); +void set_tensor_name(ngraph::Output output, const std::string & name); + +void set_tensor_names(ngraph::Output output, const std::unordered_set & names); + namespace ngraph { namespace pass { class InjectionPass; diff --git a/model-optimizer/automation/package_BOM.txt b/model-optimizer/automation/package_BOM.txt index 6f045288168..671c45fd68b 100644 --- a/model-optimizer/automation/package_BOM.txt +++ b/model-optimizer/automation/package_BOM.txt @@ -175,7 +175,6 @@ extensions/front/kaldi/tdnn_component_replacer.py extensions/front/LayerNorm.py extensions/front/Log1p.py extensions/front/MatMul_normalizer.py -extensions/front/Mish_fusion.py extensions/front/MoveEmbeddedInputsToInputs.py extensions/front/mxnet/__init__.py extensions/front/mxnet/activation.py @@ -329,12 +328,10 @@ extensions/front/onnx/priorbox_clustered_ext.py extensions/front/onnx/priorbox_ext.py extensions/front/onnx/priorgridgenerator_ext.py extensions/front/onnx/proposal_ext.py -extensions/front/onnx/quantize_dequantize_linear.py extensions/front/onnx/quantize_ext.py extensions/front/onnx/quantize_linear_ext.py extensions/front/onnx/range_ext.py extensions/front/onnx/reduce_ext.py -extensions/front/onnx/remove_filtering_boxes_by_size.py extensions/front/onnx/reshape_ext.py extensions/front/onnx/resize_ext.py extensions/front/onnx/reverse_sequence_ext.py @@ -371,13 +368,11 @@ extensions/front/RollWithEmptyAxesReplacer.py extensions/front/scatter_normalizer.py extensions/front/SizeReplacer.py extensions/front/softmax.py -extensions/front/Softplus_fusion.py extensions/front/softsign_replacer.py extensions/front/sparse_to_dense_replacer.py extensions/front/split_normalizer.py extensions/front/SqueezeNormalize.py extensions/front/sub.py -extensions/front/Swish_fusion.py extensions/front/tf/__init__.py extensions/front/tf/activation_ext.py extensions/front/tf/argmax_ext.py diff --git a/model-optimizer/extensions/front/Mish_fusion.py b/model-optimizer/extensions/front/Mish_fusion.py deleted file mode 100644 index f86ea349944..00000000000 --- a/model-optimizer/extensions/front/Mish_fusion.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright (C) 2018-2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -from extensions.front.Softplus_fusion import SoftplusFusion -from extensions.ops.activation_ops import Mish -from mo.front.common.replacement import FrontReplacementSubgraph -from mo.front.subgraph_matcher import SubgraphMatch -from mo.graph.graph import Graph, rename_nodes - - -class MishFusion(FrontReplacementSubgraph): - """ - The transformation looks for the pattern with Softplus defining the Mish function: Mish(x) = x * tanh(SoftPlus(x)). - """ - enabled = True - - def run_after(self): - return [SoftplusFusion] - - def pattern(self): - return dict( - nodes=[ - ('mul', dict(op='Mul')), - ('tanh', dict(op='Tanh')), - ('softplus', dict(op='SoftPlus')), - ], - edges=[ - ('softplus', 'tanh'), - ('tanh', 'mul'), - ]) - - def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]): - mul = match['mul'] - mul_name = mul.soft_get('name', mul.id) - softplus = match['softplus'] - - # determine the input port of Mul which gets the 'input' node output - input_port_idx = int(mul.in_port(0).get_connection().get_source().node.soft_get('op') == 'Tanh') - - # check that the same tensor provided as input to Mul and SoftPlus - if mul.in_port(input_port_idx).get_source() != softplus.in_port(0).get_source(): - return - - mish = Mish(graph, {}).create_node() - mish.in_port(0).connect(mul.in_port(input_port_idx).get_source()) - mul.out_port(0).get_connection().set_source(mish.out_port(0)) - - rename_nodes([(mul, mul_name + '/TBR'), (mish, mul_name)]) diff --git a/model-optimizer/extensions/front/Softplus_fusion.py b/model-optimizer/extensions/front/Softplus_fusion.py deleted file mode 100644 index 4d600e1b969..00000000000 --- a/model-optimizer/extensions/front/Softplus_fusion.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (C) 2018-2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -import numpy as np - -from extensions.ops.activation_ops import SoftPlus -from mo.front.common.replacement import FrontReplacementSubgraph -from mo.front.subgraph_matcher import SubgraphMatch -from mo.graph.graph import Graph, rename_nodes -from mo.middle.pattern_match import check_value - - -class SoftplusFusion(FrontReplacementSubgraph): - """ - The transformation looks for the pattern for the Softplus function: Softplus(x) = ln(1 + e^x) - """ - enabled = True - - def pattern(self): - return dict( - nodes=[ - ('exp', dict(op='Exp')), - ('add', dict(op='Add')), - ('const_1', dict(op='Const', value=lambda v: check_value(v, lambda x: np.allclose(x, 1.0, atol=1e-6)))), - ('ln', dict(op='Log')), - ], - edges=[ - ('exp', 'add', {}), - ('const_1', 'add', {}), - ('add', 'ln', {}), - ]) - - def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]): - ln = match['ln'] - exp = match['exp'] - - ln_name = ln.soft_get('name', ln.id) - - softplus = SoftPlus(graph, {}).create_node() - softplus.in_port(0).connect(exp.in_port(0).get_source()) - ln.out_port(0).get_connection().set_source(softplus.out_port(0)) - - rename_nodes([(ln, ln_name + '/TBR'), (softplus, ln_name)]) diff --git a/model-optimizer/extensions/front/Swish_fusion.py b/model-optimizer/extensions/front/Swish_fusion.py deleted file mode 100644 index 48cc69ca540..00000000000 --- a/model-optimizer/extensions/front/Swish_fusion.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright (C) 2018-2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -from extensions.ops.activation_ops import Swish -from mo.front.common.replacement import FrontReplacementSubgraph -from mo.front.subgraph_matcher import SubgraphMatch -from mo.graph.graph import Graph, rename_nodes - - -class SwishWithSigmoidWithoutBeta(FrontReplacementSubgraph): - """ - The transformation looks for the pattern with Sigmoid defining the Swish function: Swish(x) = x * Sigmoid(x) - """ - enabled = True - - def pattern(self): - return dict( - nodes=[ - ('sigmoid', dict(op='Sigmoid')), - ('mul', dict(op='Mul')), - ], - edges=[ - ('sigmoid', 'mul', {}), - ]) - - def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]): - sigmoid = match['sigmoid'] - mul = match['mul'] - mul_name = mul.soft_get('name', mul.id) - - # determine the input port of Mul which gets the 'input' node output - mul_input_port_idx = int(mul.in_port(0).get_connection().get_source().node.soft_get('op') == 'Sigmoid') - - # check that the same tensor provided as input to Mul and Sigmoid - if mul.in_port(mul_input_port_idx).get_source() != sigmoid.in_port(0).get_source(): - return - - swish = Swish(graph, {}).create_node() - swish.in_port(0).connect(sigmoid.in_port(0).get_source()) - mul.out_port(0).get_connection().set_source(swish.out_port(0)) - - rename_nodes([(mul, mul_name + '/TBR'), (swish, mul_name)]) - - -class SwishWithSigmoidWithBeta(FrontReplacementSubgraph): - """ - The transformation looks for the pattern with Sigmoid defining the Swish function: Swish(x) = x * Sigmoid(x * beta) - """ - enabled = True - - def pattern(self): - return dict( - nodes=[ - ('sigmoid', dict(op='Sigmoid')), - ('beta', dict()), - ('mul_beta', dict(op='Mul')), - ('mul', dict(op='Mul')), - ], - edges=[ - ('beta', 'mul_beta', {}), - ('mul_beta', 'sigmoid', {}), - ('sigmoid', 'mul', {}), - ]) - - def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]): - beta = match['beta'] - mul = match['mul'] - mul_beta = match['mul_beta'] - mul_name = mul.soft_get('name', mul.id) - - # determine the input port of Muls which get the 'input' node output - mul_beta_input_port_idx = int(mul_beta.in_port(0).get_connection().get_source().node.id == beta.id) - mul_input_port_idx = int(mul.in_port(0).get_connection().get_source().node.soft_get('op') == 'Sigmoid') - - # check that the same tensor provided as input to Mul and MulBeta - if mul.in_port(mul_input_port_idx).get_source() != mul_beta.in_port(mul_beta_input_port_idx).get_source(): - return - - swish = Swish(graph, {}).create_node() - swish.in_port(0).connect(mul_beta.in_port(mul_beta_input_port_idx).get_source()) - - # connect Beta value - swish.in_port(1).connect(mul_beta.in_port(1 - mul_beta_input_port_idx).get_source()) - - mul.out_port(0).get_connection().set_source(swish.out_port(0)) - - rename_nodes([(mul, mul_name + '/TBR'), (swish, mul_name)]) diff --git a/model-optimizer/extensions/front/onnx/quantize_dequantize_linear.py b/model-optimizer/extensions/front/onnx/quantize_dequantize_linear.py deleted file mode 100644 index 5607c336cd1..00000000000 --- a/model-optimizer/extensions/front/onnx/quantize_dequantize_linear.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright (C) 2018-2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -import logging as log - -import numpy as np - -from extensions.ops.fakequantize import FakeQuantize -from mo.front.common.replacement import FrontReplacementSubgraph -from mo.front.subgraph_matcher import SubgraphMatch -from mo.graph.graph import Graph, rename_nodes -from mo.ops.const import Const -from mo.utils.error import Error - - -class QuantizeDequantizeLinear(FrontReplacementSubgraph): - """ - Fuses QuantizeLinear and DequantizeLinear nodes into single FakeQuantize. - Covers cases when the values for zero point and scale are same in both QuantizeLinear and DequantizeLinear. - """ - enabled = True - - def pattern(self): - return dict( - nodes=[ - ('quantize', dict(op='QuantizeLinear')), - ('dequantize', dict(op='DequantizeLinear')), - ], - edges=[ - ('quantize', 'dequantize', {'in': 0}), - ] - ) - - def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]): - - q = match['quantize'] - dq = match['dequantize'] - - q_scale = q.in_port(1).get_source().node - q_zerop = q.in_port(2).get_source().node - dq_scale = dq.in_port(1).get_source().node - dq_zerop = dq.in_port(2).get_source().node - - inp_port = q.in_port(0).get_source() - name = inp_port.node.soft_get('name', inp_port.node.id) - - # only constant as for zero_point/scale supported - if q_scale.soft_get('type') == 'Const' and dq_scale.soft_get('type') == 'Const' and \ - q_zerop.soft_get('type') == 'Const' and dq_zerop.soft_get('type') == 'Const': - - # only patterns with same scale/zero_point values for Q and DQ are supported - if q_scale.value == dq_scale.value and q_zerop.value == dq_zerop.value: - log.debug('Found Q-DQ pattern after {}'.format(name)) - - zero_point_type = q_zerop.value.dtype - # data type affects range of output values: [-128..127] or [0..255] - if zero_point_type == np.int8: - output_min_value = -128.0 - output_max_value = 127.0 - elif zero_point_type == np.uint8: - output_min_value = 0.0 - output_max_value = 255.0 - else: - raise Error('Not supported type {} for zero point value in node {}'.format( - zero_point_type, q_zerop.soft_get('name'))) - min_value = q_scale.value * (output_min_value - q_zerop.value) - max_value = q_scale.value * (output_max_value - q_zerop.value) - input_min = Const(graph, {'value': np.array(min_value)}).create_node() - input_max = Const(graph, {'value': np.array(max_value)}).create_node() - - FQ = FakeQuantize(graph, { - 'levels': 256, - 'name': match['quantize'].name + '_Dequantize/FakeQuantize' - }).create_node() - - FQ.in_port(0).connect(match['quantize'].in_port(0).get_source()) - FQ.in_port(1).connect(input_min.out_port(0)) - FQ.in_port(2).connect(input_max.out_port(0)) - FQ.in_port(3).connect(input_min.out_port(0)) - FQ.in_port(4).connect(input_max.out_port(0)) - - match['dequantize'].out_port(0).get_connection().set_source(FQ.out_port(0)) - dq_name = match['dequantize'].soft_get('name', match['dequantize'].id) - rename_nodes([(match['dequantize'], dq_name + '/to_be_removed'), (FQ, dq_name)]) - else: - raise Error('QuantizeLinear and DequantizeLinear (after {}) have different scale or zero-point values, ' - 'cannot fuse into FakeQuantize!'.format(name)) diff --git a/model-optimizer/extensions/front/onnx/remove_filtering_boxes_by_size.py b/model-optimizer/extensions/front/onnx/remove_filtering_boxes_by_size.py deleted file mode 100644 index 01755ea4636..00000000000 --- a/model-optimizer/extensions/front/onnx/remove_filtering_boxes_by_size.py +++ /dev/null @@ -1,117 +0,0 @@ -# Copyright (C) 2018-2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -from extensions.front.split_normalizer import AttributedVariadicSplitToVariadicSplit -from extensions.ops.range import Range -from mo.front.common.partial_infer.utils import int64_array -from mo.front.common.replacement import FrontReplacementSubgraph -from mo.front.tf.graph_utils import create_op_node_with_second_input -from mo.graph.graph import Graph -from mo.graph.graph import Node -from mo.ops.const import Const -from mo.ops.shape import Shape -from mo.ops.squeeze import Squeeze -from mo.utils.shape import node_to_get_batch_value - - -def skip_nodes_by_condition(current_node: Node, condition: callable): - while condition(current_node): - current_node = current_node.in_node() - return current_node - - -class RemoveFilteringBoxesBySize(FrontReplacementSubgraph): - """ - The transformation looks for a sub-graph that selects boxes with nonzero height and width. The output node of this - sub-graph is a Cast node that produces indices of nodes to be preserved. The transformation creates a new sub-graph - that produces a tensor with values from 0 to input.shape[0] to select all boxes. The output of this sub-graph will - be used in the NonMaxSuppression so the implementation of this layer should ignore boxes with negative sizes. - """ - enabled = True - force_clean_up = True - - def run_after(self): - return [AttributedVariadicSplitToVariadicSplit] - - def pattern(self): - return dict( - nodes=[ - ('split', dict(op='VariadicSplit')), - ('sub_1', dict(op='Sub')), - ('sub_2', dict(op='Sub')), - ('add_1', dict(op='Add')), - ('add_2', dict(op='Add')), - ('concat', dict(op='Concat')), - ('split_2', dict(op='VariadicSplit')), - ('squeeze_1', dict(op='Squeeze')), - ('squeeze_2', dict(op='Squeeze')), - ('less_1', dict(op='Less')), - ('less_2', dict(op='Less')), - ('not_1', dict(op='LogicalNot')), - ('not_2', dict(op='LogicalNot')), - ('cast_11', dict(op='Cast')), - ('cast_12', dict(op='Cast')), - ('cast_21', dict(op='Cast')), - ('cast_22', dict(op='Cast')), - ('and', dict(op='LogicalAnd')), - ('cast_31', dict(op='Cast')), - ('cast_32', dict(op='Cast')), - ('nonzero', dict(op='NonZero')), - ('transpose', dict(op='Transpose')), - ('squeeze', dict(op='Squeeze')), - ('cast', dict(op='Cast')), - ], - edges=[ - ('split', 'sub_1', {'in': 0, 'out': 2}), - ('split', 'sub_1', {'in': 1, 'out': 0}), - ('split', 'sub_2', {'in': 0, 'out': 3}), - ('split', 'sub_2', {'in': 1, 'out': 1}), - ('sub_1', 'add_1', {}), - ('sub_2', 'add_2', {}), - ('split', 'concat', {'in': 0, 'out': 0}), - ('split', 'concat', {'in': 1, 'out': 1}), - ('add_1', 'concat', {'in': 2, 'out': 0}), - ('add_2', 'concat', {'in': 3, 'out': 0}), - ('concat', 'split_2', {}), - ('split_2', 'squeeze_1', {'in': 0, 'out': 2}), - ('split_2', 'squeeze_2', {'in': 0, 'out': 3}), - ('squeeze_1', 'less_1', {}), - ('squeeze_2', 'less_2', {}), - ('less_1', 'not_1', {}), - ('less_2', 'not_2', {}), - ('not_1', 'cast_11', {}), - ('cast_11', 'cast_12', {}), - ('not_2', 'cast_21', {}), - ('cast_21', 'cast_22', {}), - ('cast_12', 'and', {}), - ('cast_22', 'and', {}), - ('and', 'cast_31', {}), - ('cast_31', 'cast_32', {}), - ('cast_32', 'nonzero', {}), - ('nonzero', 'transpose', {}), - ('transpose', 'squeeze', {}), - ('squeeze', 'cast', {}), - ]) - - def replace_sub_graph(self, graph: Graph, match: dict): - source_connection = match['split'].in_port(0).get_connection() - source_node = source_connection.get_source().node - cast_node = match['cast'] - - range_node = Range(graph, {'name': source_node.id + '/Range'}).create_node() - start_node = Const(graph, {'name': range_node.id + '/Start', 'value': int64_array(0)}).create_node() - - step_node = Const(graph, {'name': range_node.id + '/Step', 'value': int64_array(1)}).create_node() - input_shape_node = Shape(graph, {'name': start_node.id + '/Shape'}).create_node() - input_shape_node.in_port(0).connect(source_node.out_port(0)) - - limit_node_1D = node_to_get_batch_value(input_shape_node) - limit_node = create_op_node_with_second_input(graph, Squeeze, int64_array([0]), - {'name': source_node.id + '/batch_0D_value'}, limit_node_1D) - - range_node.in_port(0).connect(start_node.out_port(0)) - range_node.in_port(1).connect(limit_node.out_port(0)) - range_node.in_port(2).connect(step_node.out_port(0)) - cast_node.out_port(0).get_connection().set_source(range_node.out_port(0)) - - graph.remove_nodes_from([node.id for node in match.values()]) diff --git a/model-optimizer/unit_tests/extensions/front/Mish_fusion_test.py b/model-optimizer/unit_tests/extensions/front/Mish_fusion_test.py deleted file mode 100644 index 10e48daefad..00000000000 --- a/model-optimizer/unit_tests/extensions/front/Mish_fusion_test.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright (C) 2018-2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -import unittest - -from extensions.front.Mish_fusion import MishFusion -from mo.utils.ir_engine.compare_graphs import compare_graphs -from unit_tests.utils.graph import build_graph, regular_op, result, build_graph_with_edge_attrs - -ref_nodes = {**regular_op('input', {'type': 'Parameter'}), - **regular_op('mish', {'type': 'Mish', 'name': 'final_mul'}), - **result('result') - } -ref_edges = [('input', 'mish'), ('mish', 'result')] - - -class MishFusionTest(unittest.TestCase): - nodes = { - **regular_op('input', {'type': 'Parameter'}), - **regular_op('softplus', {'op': 'SoftPlus'}), - **regular_op('tanh', {'op': 'Tanh'}), - **regular_op('mul', {'op': 'Mul', 'name': 'final_mul'}), - **result('result'), - } - - edges = [('input', 'softplus', {'in': 0, 'out': 0}), - ('input', 'mul', {'in': 0, 'out': 0}), - ('softplus', 'tanh', {'in': 0, 'out': 0}), - ('tanh', 'mul', {'in': 1, 'out': 0}), - ('mul', 'result', {'in': 0, 'out': 0})] - - def test_mish_fusion(self): - graph = build_graph_with_edge_attrs(self.nodes, self.edges, {}) - - graph_ref = build_graph(ref_nodes, ref_edges) - graph.stage = 'front' - - MishFusion().find_and_replace_pattern(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'result') - self.assertTrue(flag, resp) - self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and - graph.get_op_nodes(name='final_mul')[0].op == 'Mish') - - def test_mish_fusion_different_source(self): - # check case when different tensors goes to Mul and SoftPlus - graph = build_graph_with_edge_attrs({ - **regular_op('input', {'type': 'Parameter'}), - **regular_op('input_2', {'type': 'Parameter'}), - **regular_op('softplus', {'op': 'SoftPlus'}), - **regular_op('tanh', {'op': 'Tanh'}), - **regular_op('mul', {'op': 'Mul', 'name': 'final_mul'}), - **result('result'), - }, [('input', 'softplus', {'in': 0, 'out': 0}), - ('input_2', 'mul', {'in': 0, 'out': 0}), - ('softplus', 'tanh', {'in': 0, 'out': 0}), - ('tanh', 'mul', {'in': 1, 'out': 0}), - ('mul', 'result', {'in': 0, 'out': 0})], {}) - - graph_ref = graph.copy() - graph.stage = 'front' - - MishFusion().find_and_replace_pattern(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'result') - self.assertTrue(flag, resp) diff --git a/model-optimizer/unit_tests/extensions/front/Softplus_fusion_test.py b/model-optimizer/unit_tests/extensions/front/Softplus_fusion_test.py deleted file mode 100644 index 0dd93f8d95c..00000000000 --- a/model-optimizer/unit_tests/extensions/front/Softplus_fusion_test.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (C) 2018-2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -import unittest - -from extensions.front.Softplus_fusion import SoftplusFusion -from mo.front.common.partial_infer.utils import float_array -from mo.utils.ir_engine.compare_graphs import compare_graphs -from unit_tests.utils.graph import build_graph, const, regular_op, result, build_graph_with_edge_attrs - -ref_nodes = {**regular_op('input', {'type': 'Parameter'}), - **regular_op('softplus', {'type': 'SoftPlus', 'name': 'final_log'}), - **result('result') - } -ref_edges = [('input', 'softplus'), ('softplus', 'result')] - - -class SoftplusFusionTest(unittest.TestCase): - nodes = { - **regular_op('input', {'type': 'Parameter'}), - **regular_op('exp', {'op': 'Exp'}), - **const('const_1', float_array([1.0])), - **regular_op('add', {'op': 'Add'}), - **regular_op('ln', {'op': 'Log', 'name': 'final_log'}), - **result('result'), - } - - edges = [('input', 'exp', {'in': 0, 'out': 0}), - ('const_1', 'add', {'in': 0, 'out': 0}), - ('exp', 'add', {'in': 1, 'out': 0}), - ('add', 'ln', {'in': 0, 'out': 0}), - ('ln', 'result', {'in': 0, 'out': 0})] - - def test_softplus_fusion_test(self): - graph = build_graph_with_edge_attrs(self.nodes, self.edges, {}) - - graph_ref = build_graph(ref_nodes, ref_edges) - graph.stage = 'front' - - SoftplusFusion().find_and_replace_pattern(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'result') - self.assertTrue(flag, resp) - self.assertTrue(len(graph.get_op_nodes(name='final_log')) == 1 and - graph.get_op_nodes(name='final_log')[0].op == 'SoftPlus') - - def test_softplus_fusion_test_wrong_const(self): - graph = build_graph_with_edge_attrs(self.nodes, self.edges, {'const_1': {'value': float_array([0.9999])}}) - - graph_ref = graph.copy() - graph.stage = 'front' - - SoftplusFusion().find_and_replace_pattern(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'result') - self.assertTrue(flag, resp) - diff --git a/model-optimizer/unit_tests/extensions/front/Swish_fusion_test.py b/model-optimizer/unit_tests/extensions/front/Swish_fusion_test.py deleted file mode 100644 index ccf9985536b..00000000000 --- a/model-optimizer/unit_tests/extensions/front/Swish_fusion_test.py +++ /dev/null @@ -1,119 +0,0 @@ -# Copyright (C) 2018-2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -import unittest - -from extensions.front.Swish_fusion import SwishWithSigmoidWithoutBeta, SwishWithSigmoidWithBeta -from mo.utils.ir_engine.compare_graphs import compare_graphs -from unit_tests.utils.graph import build_graph, regular_op, result, build_graph_with_edge_attrs - -ref_nodes = {**regular_op('input', {'type': 'Parameter'}), - **regular_op('swish', {'type': 'Swish', 'name': 'final_mul'}), - **result('result') - } -ref_edges = [('input', 'swish'), ('swish', 'result')] - - -class SwishWithSigmoidWithoutBetaTest(unittest.TestCase): - nodes = { - **regular_op('input', {'type': 'Parameter'}), - **regular_op('sigmoid', {'op': 'Sigmoid'}), - **regular_op('mul', {'op': 'Mul', 'name': 'final_mul'}), - **result('result'), - } - - edges = [('input', 'mul', {'in': 0, 'out': 0}), - ('input', 'sigmoid', {'in': 0, 'out': 0}), - ('sigmoid', 'mul', {'in': 1, 'out': 0}), - ('mul', 'result', {'in': 0, 'out': 0})] - - def test_swish_with_sigmoid_without_beta_test(self): - graph = build_graph_with_edge_attrs(self.nodes, self.edges, {}) - - graph_ref = build_graph(ref_nodes, ref_edges) - graph.stage = 'front' - - SwishWithSigmoidWithoutBeta().find_and_replace_pattern(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'result') - self.assertTrue(flag, resp) - self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and - graph.get_op_nodes(name='final_mul')[0].op == 'Swish') - - def test_swish_with_sigmoid_without_beta_different_tensors(self): - graph = build_graph_with_edge_attrs({ - **regular_op('input', {'type': 'Parameter'}), - **regular_op('input_2', {'type': 'Parameter'}), - **regular_op('sigmoid', {'op': 'Sigmoid'}), - **regular_op('mul', {'op': 'Mul', 'name': 'final_mul'}), - **result('result'), - }, [('input_2', 'mul', {'in': 0, 'out': 0}), - ('input', 'sigmoid', {'in': 0, 'out': 0}), - ('sigmoid', 'mul', {'in': 1, 'out': 0}), - ('mul', 'result', {'in': 0, 'out': 0})], {}) - - graph_ref = graph.copy() - graph.stage = 'front' - - SwishWithSigmoidWithoutBeta().find_and_replace_pattern(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'result') - self.assertTrue(flag, resp) - - -class SwishWithSigmoidWithBetaTest(unittest.TestCase): - nodes = { - **regular_op('input', {'type': 'Parameter'}), - **regular_op('beta', {'type': 'Parameter'}), - **regular_op('mul_beta', {'op': 'Mul'}), - **regular_op('sigmoid', {'op': 'Sigmoid'}), - **regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}), - **result('result'), - } - - edges = [('input', 'mul_beta', {'in': 0, 'out': 0}), - ('input', 'mul_2', {'in': 0, 'out': 0}), - ('beta', 'mul_beta', {'in': 1, 'out': 0}), - ('mul_beta', 'sigmoid', {'in': 0, 'out': 0}), - ('sigmoid', 'mul_2', {'in': 1, 'out': 0}), - ('mul_2', 'result', {'in': 0, 'out': 0})] - - def test_swish_with_sigmoid_with_beta_test(self): - graph = build_graph_with_edge_attrs(self.nodes, self.edges, {}) - - new_ref_nodes = ref_nodes.copy() - new_ref_nodes.update(**regular_op('beta', {'type': 'Parameter'})) - - graph_ref = build_graph(new_ref_nodes, ref_edges + [('beta', 'swish')]) - graph.stage = 'front' - - SwishWithSigmoidWithBeta().find_and_replace_pattern(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'result') - self.assertTrue(flag, resp) - self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and - graph.get_op_nodes(name='final_mul')[0].op == 'Swish') - - def test_swish_with_sigmoid_with_beta_different_tensors(self): - graph = build_graph_with_edge_attrs({ - **regular_op('input', {'type': 'Parameter'}), - **regular_op('input_2', {'type': 'Parameter'}), - **regular_op('beta', {'type': 'Parameter'}), - **regular_op('mul_beta', {'op': 'Mul'}), - **regular_op('sigmoid', {'op': 'Sigmoid'}), - **regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}), - **result('result'), - }, [('input', 'mul_beta', {'in': 0, 'out': 0}), - ('input_2', 'mul_2', {'in': 0, 'out': 0}), - ('beta', 'mul_beta', {'in': 1, 'out': 0}), - ('mul_beta', 'sigmoid', {'in': 0, 'out': 0}), - ('sigmoid', 'mul_2', {'in': 1, 'out': 0}), - ('mul_2', 'result', {'in': 0, 'out': 0})], {}) - - graph_ref = graph.copy() - graph.stage = 'front' - - SwishWithSigmoidWithBeta().find_and_replace_pattern(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'result') - self.assertTrue(flag, resp) diff --git a/model-optimizer/unit_tests/extensions/front/onnx/quantize_dequantize_linear_test.py b/model-optimizer/unit_tests/extensions/front/onnx/quantize_dequantize_linear_test.py deleted file mode 100644 index 3d07eb06236..00000000000 --- a/model-optimizer/unit_tests/extensions/front/onnx/quantize_dequantize_linear_test.py +++ /dev/null @@ -1,115 +0,0 @@ -# Copyright (C) 2018-2021 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -import unittest - -import numpy as np - -from extensions.front.onnx.quantize_dequantize_linear import QuantizeDequantizeLinear -from mo.utils.ir_engine.compare_graphs import compare_graphs -from unit_tests.utils.graph import build_graph - -# quantize and dequantize share tensors with scale/zp -nodes0_attributes = { - 'input': {'kind': 'op', 'op': 'AnyOp'}, - 'quantize': {'kind': 'op', 'op': 'QuantizeLinear'}, - 'dequantize': {'kind': 'op', 'op': 'DequantizeLinear'}, - 'scale_param': {'kind': 'op', 'type': 'Const', 'op': 'Const'}, - 'zerop_param': {'kind': 'op', 'type': 'Const', 'op': 'Const'}, - 'out': {'kind': 'op', 'op': 'AnyOp'}, -} - -# quantize and dequantize do not share tensors with scale/zp -nodes1_attributes = { - 'input': {'kind': 'op', 'op': 'AnyOp'}, - 'quantize': {'kind': 'op', 'op': 'QuantizeLinear'}, - 'dequantize': {'kind': 'op', 'op': 'DequantizeLinear'}, - 'scale_param_q': {'kind': 'op', 'type': 'Const', 'op': 'Const'}, - 'zerop_param_q': {'kind': 'op', 'type': 'Const', 'op': 'Const'}, - 'scale_param_dq': {'kind': 'op', 'type': 'Const', 'op': 'Const'}, - 'zerop_param_dq': {'kind': 'op', 'type': 'Const', 'op': 'Const'}, - 'out': {'kind': 'op', 'op': 'AnyOp'}, -} - -nodes_ref_attributes = { - 'input': {'kind': 'op', 'op': 'AnyOp'}, - 'fq': {'kind': 'op', 'op': 'FakeQuantize'}, - 'min_param': {'kind': 'op', 'type': 'Const', 'op': 'Const'}, - 'max_param': {'kind': 'op', 'type': 'Const', 'op': 'Const'}, - 'out': {'kind': 'op', 'op': 'AnyOp'}, -} - - -class TestQuantizeDeQuantize2FakeQuantize(unittest.TestCase): - - def test_quantizedequantize2fakequantize_0(self): - # testing the code path with uint8 zero-point - graph = build_graph(nodes1_attributes, - [('input', 'quantize'), - ('quantize', 'dequantize'), - ('scale_param_q', 'quantize'), - ('zerop_param_q', 'quantize'), - ('scale_param_dq', 'dequantize'), - ('zerop_param_dq', 'dequantize'), - ('dequantize', 'out'), - ], - {'scale_param_q': {'shape': np.array([1]), 'value': np.float32(1.0 / 255)}, - 'zerop_param_q': {'shape': np.array([1]), 'value': np.uint8(0)}, - 'scale_param_dq': {'shape': np.array([1]), 'value': np.float32(1.0 / 255)}, - 'zerop_param_dq': {'shape': np.array([1]), 'value': np.uint8(0)}, - }, nodes_with_edges_only=True) - - graph_ref = build_graph(nodes_ref_attributes, - [('input', 'fq', {'in': 0}), - ('min_param', 'fq', {'out': 0, 'in': 1}), - ('min_param', 'fq', {'out': 0, 'in': 3}), - ('max_param', 'fq', {'out': 0, 'in': 2}), - ('max_param', 'fq', {'out': 0, 'in': 4}), - ('fq', 'out'), - ], - {'fq': {'levels': 256}, - 'min_param': {'value': np.float32(0.0)}, - 'max_param': {'value': np.float32(1.0)}, - }, nodes_with_edges_only=True) - - graph.stage = 'front' - tested_class = QuantizeDequantizeLinear() - tested_class.find_and_replace_pattern(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'out', check_op_attrs=True) - self.assertTrue(flag, resp) - - def test_quantizedequantize2fakequantize_1(self): - # testing the code path with int8 zero-point - graph = build_graph(nodes0_attributes, - [('input', 'quantize'), - ('quantize', 'dequantize'), - ('scale_param', 'quantize'), - ('zerop_param', 'quantize'), - ('scale_param', 'dequantize'), - ('zerop_param', 'dequantize'), - ('dequantize', 'out'), - ], - {'scale_param': {'shape': np.array([1]), 'value': np.float32(1.0 / 255)}, - 'zerop_param': {'shape': np.array([1]), 'value': np.int8(0)}, - }, nodes_with_edges_only=True) - - graph_ref = build_graph(nodes_ref_attributes, - [('input', 'fq', {'in': 0}), - ('min_param', 'fq', {'out': 0, 'in': 1}), - ('min_param', 'fq', {'out': 0, 'in': 3}), - ('max_param', 'fq', {'out': 0, 'in': 2}), - ('max_param', 'fq', {'out': 0, 'in': 4}), - ('fq', 'out'), - ], - {'fq': {'levels': 256}, - 'min_param': {'value': np.float32(-128.0 / 255)}, - 'max_param': {'value': np.float32(127.0 / 255)}, - }, nodes_with_edges_only=True) - - graph.stage = 'front' - tested_class = QuantizeDequantizeLinear() - tested_class.find_and_replace_pattern(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'out', check_op_attrs=True) - self.assertTrue(flag, resp) diff --git a/ngraph/core/include/ngraph/descriptor/tensor.hpp b/ngraph/core/include/ngraph/descriptor/tensor.hpp index 676bd9eddd0..381e528e531 100644 --- a/ngraph/core/include/ngraph/descriptor/tensor.hpp +++ b/ngraph/core/include/ngraph/descriptor/tensor.hpp @@ -45,6 +45,7 @@ namespace ngraph const std::unordered_set& get_names() const; void set_names(const std::unordered_set& names); + void add_names(const std::unordered_set& names); void set_tensor_type(const element::Type& element_type, const PartialShape& pshape); void set_element_type(const element::Type& elemenet_type); void set_partial_shape(const PartialShape& partial_shape); diff --git a/ngraph/core/src/descriptor/tensor.cpp b/ngraph/core/src/descriptor/tensor.cpp index 58b06df90ad..1d8335fee08 100644 --- a/ngraph/core/src/descriptor/tensor.cpp +++ b/ngraph/core/src/descriptor/tensor.cpp @@ -123,6 +123,14 @@ void descriptor::Tensor::set_names(const std::unordered_set& names) m_names = names; } +void descriptor::Tensor::add_names(const std::unordered_set& names) +{ + for (const auto& name : names) + { + m_names.insert(name); + } +} + ostream& operator<<(ostream& out, const descriptor::Tensor& tensor) { std::string names; diff --git a/ngraph/core/src/graph_util.cpp b/ngraph/core/src/graph_util.cpp index 12a439f17e3..901672723a1 100644 --- a/ngraph/core/src/graph_util.cpp +++ b/ngraph/core/src/graph_util.cpp @@ -167,11 +167,9 @@ void ngraph::replace_node(std::shared_ptr target, // Change I's connected upstream output to O_rep for (size_t i = 0; i < target->get_output_size(); i++) { - for (auto& input : target->output(i).get_target_inputs()) - { - input.replace_source_output(replacement->output(output_order[i])); - } + target->output(i).replace(replacement->output(output_order[i])); } + replacement->add_node_control_dependents(target); replacement->add_node_control_dependencies(target); target->clear_control_dependents(); @@ -912,7 +910,15 @@ bool ngraph::replace_output_update_name(Output output, const Output& replacement.get_tensor().set_name(output.get_node()->get_friendly_name()); NGRAPH_SUPPRESS_DEPRECATED_END } + + // Save replacement tensor names before replacement as they will be + // overrided by the output tensor names + auto output_names = replacement.get_tensor_ptr()->get_names(); output.replace(replacement); + + // Restore back original replacement tensor names + replacement.get_tensor().add_names(output_names); + copy_runtime_info({replacement.get_node_shared_ptr(), output.get_node_shared_ptr()}, replacement.get_node_shared_ptr()); return true; diff --git a/ngraph/core/src/node_output.cpp b/ngraph/core/src/node_output.cpp index 9799c49b8fa..e64dd472f35 100644 --- a/ngraph/core/src/node_output.cpp +++ b/ngraph/core/src/node_output.cpp @@ -76,6 +76,7 @@ namespace ngraph { input.replace_source_output(replacement); } + replacement.get_tensor_ptr()->set_names(get_tensor_ptr()->get_names()); } using RTMap = std::map>; diff --git a/ngraph/core/src/op/util/scatter_nd_base.cpp b/ngraph/core/src/op/util/scatter_nd_base.cpp index c8a1d13931c..9040645cdd2 100644 --- a/ngraph/core/src/op/util/scatter_nd_base.cpp +++ b/ngraph/core/src/op/util/scatter_nd_base.cpp @@ -57,11 +57,13 @@ void op::util::ScatterNDBase::validate_and_infer_types() NODE_VALIDATION_CHECK(this, inputs_rank.is_dynamic() || indices_rank.is_dynamic() || + indices_shape[indices_rank.get_length() - 1].is_dynamic() || indices_shape[indices_rank.get_length() - 1].get_length() <= inputs_rank.get_length(), "Last dimension of indices can be at most the rank of inputs"); - if (inputs_rank.is_static() && indices_rank.is_static() && updates_rank.is_static()) + if (inputs_rank.is_static() && indices_rank.is_static() && updates_rank.is_static() && + indices_shape[indices_rank.get_length() - 1].is_static()) { auto expected_updates_rank = indices_rank.get_length() + inputs_rank.get_length() - indices_shape[indices_rank.get_length() - 1].get_length() - 1; diff --git a/ngraph/test/replace_node.cpp b/ngraph/test/replace_node.cpp index 498fb8ad1d7..c69b73d1623 100644 --- a/ngraph/test/replace_node.cpp +++ b/ngraph/test/replace_node.cpp @@ -108,3 +108,63 @@ TEST(replace_node, replace_nodes) ASSERT_EQ(z_replacement->get_input_node_shared_ptr(0), x_replacement); ASSERT_EQ(z_replacement->get_input_node_shared_ptr(1), mul); } + +TEST(replace_node, simple_node_replacement) +{ + auto param = std::make_shared(element::i64, Shape{1, 64}); + param->output(0).get_tensor().set_names({"a", "b"}); + auto relu = std::make_shared(param); + relu->output(0).get_tensor().set_names({"c", "d"}); + + auto new_relu = std::make_shared(param); + new_relu->output(0).get_tensor().set_names({"f"}); + replace_node(relu, new_relu); + + ASSERT_EQ(new_relu->output(0).get_tensor().get_names(), std::unordered_set({"c", "d"})); +} + +TEST(replace_node, node_elimination) +{ + auto param = std::make_shared(element::i64, Shape{1, 64}); + param->output(0).get_tensor().set_names({"a", "b"}); + auto relu1 = std::make_shared(param); + relu1->output(0).get_tensor().set_names({"c", "d"}); + auto relu2 = std::make_shared(relu1); + relu2->output(0).get_tensor().set_names({"e", "f"}); + + ASSERT_TRUE(replace_output_update_name(relu2->output(0), relu2->input_value(0))); + ASSERT_EQ(relu1->output(0).get_tensor().get_names(), std::unordered_set({"c", "d", "e", "f"})); + ASSERT_EQ(param->output(0).get_tensor().get_names(), std::unordered_set({"a", "b"})); +} + +TEST(replace_node, output_replacement) +{ + auto param = std::make_shared(element::i64, Shape{1, 64}); + param->output(0).get_tensor().set_names({"a", "b"}); + auto relu = std::make_shared(param); + relu->output(0).get_tensor().set_names({"c", "d"}); + + auto new_relu = std::make_shared(param); + new_relu->output(0).get_tensor().set_names({"f"}); + + relu->output(0).replace(new_relu->output(0)); + + ASSERT_EQ(new_relu->output(0).get_tensor().get_names(), std::unordered_set({"c", "d"})); +} + +TEST(replace_node, source_replacement) +{ + auto param = std::make_shared(element::i64, Shape{1, 64}); + param->output(0).get_tensor().set_names({"a", "b"}); + + auto param1 = std::make_shared(element::i64, Shape{1, 64}); + param1->output(0).get_tensor().set_names({"c", "d"}); + + auto relu = std::make_shared(param); + relu->input(0).replace_source_output(param1->output(0)); + + ASSERT_EQ(param->output(0).get_tensor().get_names(), std::unordered_set({"a", "b"})); + ASSERT_EQ(param1->output(0).get_tensor().get_names(), std::unordered_set({"c", "d"})); +} + +