void load(const json11::Json& src, ppconsul::catalog::NodeServices& dst)

#include "ppconsul/catalog.h"
#include "s11n_types.h"

namespace json11 {
    void load(const json11::Json& src, ppconsul::catalog::NodeService& dst)
    {
        using ppconsul::s11n::load;

        load(src, dst.first);
        load(src, dst.second.id, "ServiceID");
        load(src, dst.second.name, "ServiceName");
        load(src, dst.second.address, "ServiceAddress");
        load(src, dst.second.port, "ServicePort");
        load(src, dst.second.tags, "ServiceTags");
        load(src, dst.second.meta, "ServiceMeta");
    }

{
        using ppconsul::s11n::load;

        load(src, dst.first, "Node");
        load(src, dst.second, "Services");
    }
}

namespace ppconsul { namespace catalog {

namespace impl {

    StringList parseDatacenters(const std::string& json)
    {
        return s11n::parseJson<StringList>(json);
    }

    std::vector<Node> parseNodes(const std::string& json)
    {
        return s11n::parseJson<std::vector<Node>>(json);
    }

    NodeServices parseNode(const std::string& json)
    {
        return s11n::parseJson<NodeServices>(json);
    }

    std::map<std::string, Tags> parseServices(const std::string& json)
    {
        return s11n::parseJson<std::map<std::string, Tags>>(json);
    }

    std::vector<NodeService> parseService(const std::string& json)
    {
        return s11n::parseJson<std::vector<NodeService>>(json);
    }

}
}}


{
        using ppconsul::s11n::load;

        load(src, dst.first, "Node");
        load(src, dst.second, "Services");
    }

#include "ppconsul/catalog.h"
#include "s11n_types.h"

namespace json11 {
    void load(const json11::Json& src, ppconsul::catalog::NodeService& dst)
    {
        using ppconsul::s11n::load;

        load(src, dst.first);
        load(src, dst.second.id, "ServiceID");
        load(src, dst.second.name, "ServiceName");
        load(src, dst.second.address, "ServiceAddress");
        load(src, dst.second.port, "ServicePort");
        load(src, dst.second.tags, "ServiceTags");
        load(src, dst.second.meta, "ServiceMeta");
    }

    void load(const json11::Json& src, ppconsul::catalog::NodeServices& dst)

}

namespace ppconsul { namespace catalog {

namespace impl {

    StringList parseDatacenters(const std::string& json)
    {
        return s11n::parseJson<StringList>(json);
    }

    std::vector<Node> parseNodes(const std::string& json)
    {
        return s11n::parseJson<std::vector<Node>>(json);
    }

    NodeServices parseNode(const std::string& json)
    {
        return s11n::parseJson<NodeServices>(json);
    }

    std::map<std::string, Tags> parseServices(const std::string& json)
    {
        return s11n::parseJson<std::map<std::string, Tags>>(json);
    }

    std::vector<NodeService> parseService(const std::string& json)
    {
        return s11n::parseJson<std::vector<NodeService>>(json);
    }

}
}}


#include "ppconsul/catalog.h"
#include "s11n_types.h"

namespace json11 {
    void load(const json11::Json& src, ppconsul::catalog::NodeService& dst)
    {
        using ppconsul::s11n::load;

        load(src, dst.first);
        load(src, dst.second.id, "ServiceID");
        load(src, dst.second.name, "ServiceName");
        load(src, dst.second.address, "ServiceAddress");
        load(src, dst.second.port, "ServicePort");
        load(src, dst.second.tags, "ServiceTags");
        load(src, dst.second.meta, "ServiceMeta");
    }

    void load(const json11::Json& src, ppconsul::catalog::NodeServices& dst)
    {
        using ppconsul::s11n::load;

        load(src, dst.first, "Node");
        load(src, d

    }
}

namespace ppconsul { namespace catalog {

namespace impl {

    StringList parseDatacenters(const std::string& json)
    {
        return s11n::parseJson<StringList>(json);
    }

    std::vector<Node> parseNodes(const std::string& json)
    {
        return s11n::parseJson<std::vector<Node>>(json);
    }

    NodeServices parseNode(const std::string& json)
    {
        return s11n::parseJson<NodeServices>(json);
    }

    std::map<std::string, Tags> parseServices(const std::string& json)
    {
        return s11n::parseJson<std::map<std::string, Tags>>(json);
    }

    std::vector<NodeService> parseService(const std::string& json)
    {
        return s11n::parseJson<std::vector<NodeService>>(json);
    }

}
}}


#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string>
#include <iostream>
#include <dirent.h>
#include <cstring>
#include <errno.h>
#include <attr/xattr.h>

#include "../BaseTestCase.h"
#include "../../user_tools/api/workload.h"
#include "../../user_tools/api/actions.h"

using fs_testing::tests::DataTestResult;
using fs_testing::user_tools::api::WriteData;
using fs_testing::user_tools::api::WriteDataMmap;
using fs_testing::user_tools::api::Checkpoint;
using std::string;

#define TEST_FILE_PERMS  ((mode_t) (S_IRWXU | S_IRWXG | S_IRWXO))

namespace fs_testing {
    namespace tests {

        class testName: public BaseTestCase {

            public:

            virtual int setup() override {

				test_path = mnt_dir_ ;
				A_path = mnt_dir_ + "/A";
				AC_path = mnt_dir_ + "/A/C";
				B_path = mnt_dir_ + "/B";
				foo_path = mnt_dir_ + "/foo";
				bar_path = mnt_dir_ + "/bar";
				Afoo_path = mnt_dir_ + "/A/foo";
				Abar_path = mnt_dir_ + "/A/bar";
				Bfoo_path = mnt_dir_ + "/B/foo";
				Bbar_path = mnt_dir_ + "/B/bar";
				ACfoo_path = mnt_dir_ + "/A/C/foo";
				ACbar_path = mnt_dir_ + "/A/C/bar";
                return 0;
            }

            virtual int run( int checkpoint ) override {

				test_path = mnt_dir_ ;
				A_path =  mnt_dir_ + "/A";
				AC_path =  mnt_dir_ + "/A/C";
				B_path =  mnt_dir_ + "/B";
				foo_path =  mnt_dir_ + "/foo";
				bar_path =  mnt_dir_ + "/bar";
				Afoo_path =  mnt_dir_ + "/A/foo";
				Abar_path =  mnt_dir_ + "/A/bar";
				Bfoo_path =  mnt_dir_ + "/B/foo";
				Bbar_path =  mnt_dir_ + "/B/bar";
				ACfoo_path =  mnt_dir_ + "/A/C/foo";
				ACbar_path =  mnt_dir_ + "/A/C/bar";
				int local_checkpoint = 0 ;

				if ( mkdir(A_path.c_str() , 0777) < 0){
					return errno;
				}

				int fd_Afoo = cm_->CmOpen(Afoo_path.c_str() , O_RDWR|O_CREAT , 0777);
				if ( fd_Afoo < 0 ) {
					cm_->CmClose( fd_Afoo);
					return errno;
				}

				if ( WriteData ( fd_Afoo, 0, 32768) < 0){
					cm_->CmClose( fd_Afoo);
					return errno;
				}

				if ( fallocate( fd_Afoo , FALLOC_FL_ZERO_RANGE , 0 , 5000) < 0){
					cm_->CmClose( fd_Afoo);
					 return errno;
				}

				int fd_A = cm_->CmOpen(A_path.c_str() , O_DIRECTORY , 0777);
				if ( fd_A < 0 ) {
					cm_->CmClose( fd_A);
					return errno;
				}

				if ( cm_->CmFsync( fd_A) < 0){
					return errno;
				}

				if ( cm_->CmCheckpoint() < 0){
					return -1;
				}
				local_checkpoint += 1;
				if (local_checkpoint == checkpoint) {
					return 1;
				}

				if ( cm_->CmClose ( fd_Afoo) < 0){
					return errno;
				}

				if ( cm_->CmClose ( fd_A) < 0){
					return errno;
				}

                return 0;
            }

            virtual int check_test( unsigned int last_checkpoint, DataTestResult *test_result) override {

				test_path = mnt_dir_ ;
				A_path =  mnt_dir_ + "/A";
				AC_path =  mnt_dir_ + "/A/C";
				B_path =  mnt_dir_ + "/B";
				foo_path =  mnt_dir_ + "/foo";
				bar_path =  mnt_dir_ + "/bar";
				Afoo_path =  mnt_dir_ + "/A/foo";
				Abar_path =  mnt_dir_ + "/A/bar";
				Bfoo_path =  mnt_dir_ + "/B/foo";
				Bbar_path =  mnt_dir_ + "/B/bar";
				ACfoo_path =  mnt_dir_ + "/A/C/foo";
				ACbar_path =  mnt_dir_ + "/A/C/bar";
                return 0;
            }

            private:

			 string test_path;
			 string A_path;
			 string AC_path;
			 string B_path;
			 string foo_path;
			 string bar_path;
			 string Afoo_path;
			 string Abar_path;
			 string Bfoo_path;
			 string Bbar_path;
			 string ACfoo_path;
			 string ACbar_path;

            };

    }  // namespace tests
    }  // namespace fs_testing

   extern "C" fs_testing::tests::BaseTestCase *test_case_get_instance() {
       return new fs_testing::tests::testName;
   }

   extern "C"


#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string>
#include <iostream>
#include <dirent.h>
#include <cstring>
#include <errno.h>
#include <attr/xattr.h>

#include "../BaseTestCase.h"
#include "../../user_tools/api/workload.h"
#include "../../user_tools/api/actions.h"

using fs_testing::tests::DataTestResult;
using fs_testing::user_tools::api::WriteData;
using fs_testing::user_tools::api::WriteDataMmap;
using fs_testing::user_tools::api::Checkpoint;
using std::string;

#define TEST_FILE_PERMS  ((mode_t) (S_IRWXU | S_IRWXG | S_IRWXO))

namespace fs_testing {
    namespace tests {

        class testName: public BaseTestCase {

            public:

            virtual int setup() override {

				test_path = mnt_dir_ ;
				A_path = mnt_dir_ + "/A";
				AC_path = mnt_dir_ + "/A/C";
				B_path = mnt_dir_ + "/B";
				foo_path = mnt_dir_ + "/foo";
				bar_path = mnt_dir_ + "/bar";
				Afoo_path = mnt_dir_ + "/A/foo";
				Abar_path = mnt_dir_ + "/A/bar";
				Bfoo_path = mnt_dir_ + "/B/foo";
				Bbar_path = mnt_dir_ + "/B/bar";
				ACfoo_path = mnt_dir_ + "/A/C/foo";
				ACbar_path = mnt_dir_ + "/A/C/bar";
                return 0;
            }

            virtual int run( int checkpoint ) override {

				test_path = mnt_dir_ ;
				A_path =  mnt_dir_ + "/A";
				AC_path =  mnt_dir_ + "/A/C";
				B_path =  mnt_dir_ + "/B";
				foo_path =  mnt_dir_ + "/foo";
				bar_path =  mnt_dir_ + "/bar";
				Afoo_path =  mnt_dir_ + "/A/foo";
				Abar_path =  mnt_dir_ + "/A/bar";
				Bfoo_path =  mnt_dir_ + "/B/foo";
				Bbar_path =  mnt_dir_ + "/B/bar";
				ACfoo_path =  mnt_dir_ + "/A/C/foo";
				ACbar_path =  mnt_dir_ + "/A/C/bar";
				int local_checkpoint = 0 ;

				if ( mkdir(A_path.c_str() , 0777) < 0){
					return errno;
				}

				int fd_Afoo = cm_->CmOpen(Afoo_path.c_str() , O_RDWR|O_CREAT , 0777);
				if ( fd_Afoo < 0 ) {
					cm_->CmClose( fd_Afoo);
					return errno;
				}

				if ( WriteData ( fd_Afoo, 0, 32768) < 0){
					cm_->CmClose( fd_Afoo);
					return errno;
				}

				if ( fallocate( fd_Afoo , FALLOC_FL_ZERO_RANGE , 0 , 5000) < 0){
					cm_->CmClose( fd_Afoo);
					 return errno;
				}

				int fd_A = cm_->CmOpen(A_path.c_str() , O_DIRECTORY , 0777);
				if ( fd_A < 0 ) {
					cm_->CmClose( fd_A);
					return errno;
				}

				if ( cm_->CmFsync( fd_A) < 0){
					return errno;
				}

				if ( cm_->CmCheckpoint() < 0){
					return -1;
				}
				local_checkpoint += 1;
				if (local_checkpoint == checkpoint) {
					return 1;
				}

				if ( cm_->CmClose ( fd_Afoo) < 0){
					return errno;
				}

				if ( cm_->CmClose ( fd_A) < 0){
					return errno;
				}

                return 0;
            }

            virtual int check_test( unsigned int last_checkpoint, DataTestResult *test_result) override {

				test_path = mnt_dir_ ;
				A_path =  mnt_dir_ + "/A";
				AC_path =  mnt_dir_ + "/A/C";
				B_path =  mnt_dir_ + "/B";
				foo_path =  mnt_dir_ + "/foo";
				bar_path =  mnt_dir_ + "/bar";
				Afoo_path =  mnt_dir_ + "/A/foo";
				Abar_path =  mnt_dir_ + "/A/bar";
				Bfoo_path =  mnt_dir_ + "/B/foo";
				Bbar_path =  mnt_dir_ + "/B/bar";
				ACfoo_path =  mnt_dir_ + "/A/C/foo";
				ACbar_path =  mnt_dir_ + "/A/C/bar";
                return 0;
            }

            private:

			 string test_path;
			 string A_path;
			 string AC_path;
			 string B_path;
			 string foo_path;
			 string bar_path;
			 string Afoo_path;
			 string Abar_path;
			 string Bfoo_path;
			 string Bbar_path;
			 string ACfoo_path;
			 string ACbar_path;

            };

    }  // namespace tests
    }  // namespace fs_testing

   extern "C" fs_testing::tests::BaseTestCase *test_case_get_instance() {
       return new fs_testing::tests::testName;
   }

   extern "C" void test_case_delete_instance(fs_testing::tests::BaseTestCase *tc)


#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string>
#include <iostream>
#include <dirent.h>
#include <cstring>
#include <errno.h>
#include <attr/xattr.h>

#include "../BaseTestCase.h"
#include "../../user_tools/api/workload.h"
#include "../../user_tools/api/actions.h"

using fs_testing::tests::DataTestResult;
using fs_testing::user_tools::api::WriteData;
using fs_testing::user_tools::api::WriteDataMmap;
using fs_testing::user_tools::api::Checkpoint;
using std::string;

#define TEST_FILE_PERMS  ((mode_t) (S_IRWXU | S_IRWXG | S_IRWXO))

namespace fs_testing {
    namespace tests {

        class testName: public BaseTestCase {

            public:

            virtual int setup() override {

				test_path = mnt_dir_ ;
				A_path = mnt_dir_ + "/A";
				AC_path = mnt_dir_ + "/A/C";
				B_path = mnt_dir_ + "/B";
				foo_path = mnt_dir_ + "/foo";
				bar_path = mnt_dir_ + "/bar";
				Afoo_path = mnt_dir_ + "/A/foo";
				Abar_path = mnt_dir_ + "/A/bar";
				Bfoo_path = mnt_dir_ + "/B/foo";
				Bbar_path = mnt_dir_ + "/B/bar";
				ACfoo_path = mnt_dir_ + "/A/C/foo";
				ACbar_path = mnt_dir_ + "/A/C/bar";
                return

            }

            virtual int run( int checkpoint ) override {

				test_path = mnt_dir_ ;
				A_path =  mnt_dir_ + "/A";
				AC_path =  mnt_dir_ + "/A/C";
				B_path =  mnt_dir_ + "/B";
				foo_path =  mnt_dir_ + "/foo";
				bar_path =  mnt_dir_ + "/bar";
				Afoo_path =  mnt_dir_ + "/A/foo";
				Abar_path =  mnt_dir_ + "/A/bar";
				Bfoo_path =  mnt_dir_ + "/B/foo";
				Bbar_path =  mnt_dir_ + "/B/bar";
				ACfoo_path =  mnt_dir_ + "/A/C/foo";
				ACbar_path =  mnt_dir_ + "/A/C/bar";
				int local_checkpoint = 0 ;

				if ( mkdir(A_path.c_str() , 0777) < 0){
					return errno;
				}

				int fd_Afoo = cm_->CmOpen(Afoo_path.c_str() , O_RDWR|O_CREAT , 0777);
				if ( fd_Afoo < 0 ) {
					cm_->CmClose( fd_Afoo);
					return errno;
				}

				if ( WriteData ( fd_Afoo, 0, 32768) < 0){
					cm_->CmClose( fd_Afoo);
					return errno;
				}

				if ( fallocate( fd_Afoo , FALLOC_FL_ZERO_RANGE , 0 , 5000) < 0){
					cm_->CmClose( fd_Afoo);
					 return errno;
				}

				int fd_A = cm_->CmOpen(A_path.c_str() , O_DIRECTORY , 0777);
				if ( fd_A < 0 ) {
					cm_->CmClose( fd_A);
					return errno;
				}

				if ( cm_->CmFsync( fd_A) < 0){
					return errno;
				}

				if ( cm_->CmCheckpoint() < 0){
					return -1;
				}
				local_checkpoint += 1;
				if (local_checkpoint == checkpoint) {
					return 1;
				}

				if ( cm_->CmClose ( fd_Afoo) < 0){
					return errno;
				}

				if ( cm_->CmClose ( fd_A) < 0){
					return errno;
				}

                return 0;
            }

            virtual int check_test( unsigned int last_checkpoint, DataTestResult *test_result) override {

				test_path = mnt_dir_ ;
				A_path =  mnt_dir_ + "/A";
				AC_path =  mnt_dir_ + "/A/C";
				B_path =  mnt_dir_ + "/B";
				foo_path =  mnt_dir_ + "/foo";
				bar_path =  mnt_dir_ + "/bar";
				Afoo_path =  mnt_dir_ + "/A/foo";
				Abar_path =  mnt_dir_ + "/A/bar";
				Bfoo_path =  mnt_dir_ + "/B/foo";
				Bbar_path =  mnt_dir_ + "/B/bar";
				ACfoo_path =  mnt_dir_ + "/A/C/foo";
				ACbar_path =  mnt_dir_ + "/A/C/bar";
                return 0;
            }

            private:

			 string test_path;
			 string A_path;
			 string AC_path;
			 string B_path;
			 string foo_path;
			 string bar_path;
			 string Afoo_path;
			 string Abar_path;
			 string Bfoo_path;
			 string Bbar_path;
			 string ACfoo_path;
			 string ACbar_path;

            };

    }  // namespace tests
    }  // namespace fs_testing

   extern "C" fs_testing::tests::BaseTestCase *test_case_get_instance() {
       return new fs_testing::tests::testName;
   }

   extern "C" void test_case_delete_instance(fs_testing::tests::BaseTestCase *tc) {
       delete tc;
   }


/*
 * its licensors.
 *
 *
 */

#include <AzCore/IO/SystemFile.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/Utils/Utils.h>

namespace UnitTest
{
    class UtilsTestFixture
        : public ScopedAllocatorSetupFixture
    {
    };

    TEST_F(UtilsTestFixture, GetExecutablePath_ReturnsValidPath)
    {
        char executablePath[AZ_MAX_PATH_LEN];
        AZ::Utils::GetExecutablePathReturnType result = AZ::Utils::GetExecutablePath(executablePath, AZ_MAX_PATH_LEN);
        ASSERT_TRUE(result.m_pathStored == AZ::Utils::ExecutablePathResult::Success);
        EXPECT_TRUE(result.m_pathIncludesFilename);
        EXPECT_GT(strlen(executablePath), 0);
    }

{
        char executablePath[1];
        AZ::Utils::GetExecutablePathReturnType result = AZ::Utils::GetExecutablePath(executablePath, 1);
        EXPECT_EQ(AZ::Utils::ExecutablePathResult::BufferSizeNotLargeEnough, result.m_pathStored);
    }
}


{
        char executablePath[AZ_MAX_PATH_LEN];
        AZ::Utils::GetExecutablePathReturnType result = AZ::Utils::GetExecutablePath(executablePath, AZ_MAX_PATH_LEN);
        ASSERT_TRUE(result.m_pathStored == AZ::Utils::ExecutablePathResult::Success);
        EXPECT_TRUE(result.m_pathIncludesFilename);
        EXPECT_GT(strlen(executablePath), 0);
    }

/*
 * its licensors.
 *
 *
 */

#include <AzCore/IO/SystemFile.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/Utils/Utils.h>

namespace UnitTest
{
    class UtilsTestFixture
        : public ScopedAllocatorSetupFixture
    {
    };

    TEST_F(UtilsTestFixture, GetExecutablePath_ReturnsValidPath)

    TEST_F(UtilsTestFixture, GetExecutablePath_ReturnsBufferSizeTooLarge)
    {
        char executablePath[1];
        AZ::Utils::GetExecutablePathReturnType result = AZ::Utils::GetExecutablePath(executablePath, 1);
        EXPECT_EQ(AZ::Utils::ExecutablePathResult::BufferSizeNotLargeEnough, result.m_pathStored);
    }
}


/*
 * its licensors.
 *
 *
 */

#include <AzCore/IO/SystemFile.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/Utils/Utils.h>

namespace UnitTest
{
    class UtilsTestFixture
        : public ScopedAllocatorSetupFixture
    {
    };

    TEST_F(UtilsTestFixture, GetExecutablePath_ReturnsValidPath)
    {
        char executablePath[AZ_M

        AZ::Utils::GetExecutablePathReturnType result = AZ::Utils::GetExecutablePath(executablePath, AZ_MAX_PATH_LEN);
        ASSERT_TRUE(result.m_pathStored == AZ::Utils::ExecutablePathResult::Success);
        EXPECT_TRUE(result.m_pathIncludesFilename);
        EXPECT_GT(strlen(executablePath), 0);
    }

    TEST_F(UtilsTestFixture, GetExecutablePath_ReturnsBufferSizeTooLarge)
    {
        char executablePath[1];
        AZ::Utils::GetExecutablePathReturnType result = AZ::Utils::GetExecutablePath(executablePath, 1);
        EXPECT_EQ(AZ::Utils::ExecutablePathResult::BufferSizeNotLargeEnough, result.m_pathStored);
    }
}


static std::string getTestCaseName(testing::TestParamInfo<PadTransformationParams> obj)

#include "layer_transformation.hpp"

#include <string>
#include <sstream>
#include <gtest/gtest.h>
#include <ngraph/ngraph.hpp>

#include <low_precision/pad.hpp>

#include "common_test_utils/ngraph_test_utils.hpp"
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
#include "lpt_ngraph_functions/pad_function.hpp"
#include "simple_low_precision_transformer.hpp"

namespace {
using namespace testing;
using namespace ngraph;
using namespace ngraph::pass;

class PadTransformationTestValues {
public:
    class Actual {
    public:
        ngraph::element::Type precisionBeforeDequantization;
        ngraph::builder::subgraph::DequantizationOperations dequantization;
    };

    class Expected {
    public:
        ngraph::element::Type precisionBeforeDequantization;
        ngraph::builder::subgraph::DequantizationOperations dequantizationBefore;
        ngraph::element::Type precisionAfterOperation;
        ngraph::builder::subgraph::DequantizationOperations dequantizationAfter;
    };

    TestTransformationParams params;
    Actual actual;
    Expected expected;
};

typedef std::tuple <
    ngraph::PartialShape, // input Shape
    std::pair<std::vector<uint64_t>, std::vector<uint64_t>>, // pads begin, pads end
    ngraph::op::PadMode, // pads mode
    float, // pads value (used if mode == CONSTANT)
    PadTransformationTestValues> PadTransformationParams;

class PadTransformation : public LayerTransformation, public testing::WithParamInterface<PadTransformationParams> {
public:
    void SetUp() override {
        const ngraph::PartialShape inputShape = std::get<0>(GetParam());
        const auto pads = std::get<1>(GetParam());
        const ngraph::op::PadMode padsMode = std::get<2>(GetParam());
        const float padsValue = std::get<3>(GetParam());
        const PadTransformationTestValues testValues = std::get<4>(GetParam());

        const auto precisionAfterActualOp = testValues.actual.dequantization.convert.empty() ?
            testValues.actual.precisionBeforeDequantization : testValues.actual.dequantization.convert.outPrecision;

        actualFunction = ngraph::builder::subgraph::PadFunction::get(
            inputShape,
            testValues.actual.precisionBeforeDequantization,
            testValues.actual.dequantization,
            pads.first,
            pads.second,
            padsMode,
            padsValue,
            precisionAfterActualOp,
            { {}, {}, {} });

        SimpleLowPrecisionTransformer transformer;
        transformer.add<ngraph::pass::low_precision::PadTransformation, ngraph::opset1::Pad>(testValues.params);
        transformer.transform(actualFunction);

        referenceFunction = ngraph::builder::subgraph::PadFunction::get(
            inputShape,
            testValues.expected.precisionBeforeDequantization,
            testValues.expected.dequantizationBefore,
            pads.first,
            pads.second,
            padsMode,
            padsValue,
            testValues.expected.precisionAfterOperation,
            testValues.expected.dequantizationAfter);
    }

{
        const ngraph::PartialShape inputShape = std::get<0>(obj.param);
        const auto pads = std::get<1>(obj.param);
        const ngraph::op::PadMode padsMode = std::get<2>(obj.param);
        const float padsValue = std::get<3>(obj.param);
        const PadTransformationTestValues testValues = std::get<4>(obj.param);

        std::ostringstream result;
        result << "mode_" << padsMode << "_";
        if (padsMode == ngraph::op::PadMode::CONSTANT) {
            result << "pad_value_{ " << padsValue << " }";
        }

        result << "_" <<
            toString(testValues.params) << "_" <<
            inputShape << "_" << pads.first << "_" << pads.second << "_" <<
            testValues.actual.precisionBeforeDequantization << "_" <<
            testValues.actual.dequantization << "_" <<
            testValues.expected.dequantizationBefore;

        return result.str();
    }
};

TEST_P(PadTransformation, CompareFunctions) {
    actualFunction->validate_nodes_and_infer_types();
    auto res = compare_functions(referenceFunction, actualFunction, true, true);
    ASSERT_TRUE(res.first) << res.second;

    ASSERT_TRUE(LayerTransformation::allNamesAreUnique(actualFunction)) << "Not all names are unique";
}

const std::vector<ngraph::PartialShape> inputShapes = {
    {1, 3, 6, 6},
    {4, 3, 6, 6},
    {Dimension::dynamic(), 3, 6, Dimension::dynamic()}
};

const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> padsBySpatialDimensions = {
    {0, 0, 2, 1},
    {0, 0, 1, 2}
};

// test-cases with common logic for all modes
// (per-tensor & per-channel quantizations without subtracts, pads by spatial dimensions)
// and test-case without dequantization
namespace commonTestCases {
std::vector<ngraph::op::PadMode> allModes = {
    ngraph::op::PadMode::EDGE,
    ngraph::op::PadMode::REFLECT,
    ngraph::op::PadMode::SYMMETRIC,
    ngraph::op::PadMode::CONSTANT,
};

const std::vector<PadTransformationTestValues> deqWithoutSub = {
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{}, {}, {}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::f32,
            {{}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::f32,
            {{}, {}, {}},
            ngraph::element::f32,
            {{}, {}, {{3.f, 1.f, 2.f}}}
        }
    },
    {
        LayerTransformation::createParamsU8I8().setUpdatePrecisions(false),
        {
            ngraph::element::f32,
            {{}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::f32,
            {{}, {}, {}},
            ngraph::element::f32,
            {{}, {}, {{3.f, 1.f, 2.f}}}
        }
    }
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::ValuesIn(allModes),
        ::testing::Values(0.f),
        ::testing::ValuesIn(deqWithoutSub)),
    PadTransformation::getTestCaseName);
} // namespace commonTestCases

// test-cases with common logic for "EDGE", "REFLECT", and "SYMMETRIC" modes:
// pads by spatial dimensions, dequantization with subtract
namespace dqWithSubtract {
std::vector<ngraph::op::PadMode> modesInWhichSubPropagated = {
    ngraph::op::PadMode::EDGE,
    ngraph::op::PadMode::REFLECT,
    ngraph::op::PadMode::SYMMETRIC,
};

const std::vector<PadTransformationTestValues> deqWithSub = {
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {128.f}, {3.f}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {128.f}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {64.f}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {64.f}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}}
        }
    }
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::ValuesIn(modesInWhichSubPropagated),
        ::testing::Values(0.f),
        ::testing::ValuesIn(deqWithSub)),
    PadTransformation::getTestCaseName);
} // namespace dqWithSubtract

// dequantization with subtract and "CONSTANT" mode, also dequantization and padding by the same dimension
namespace testCasesForConstantMode {
const std::vector<PadTransformationTestValues> testValuesForConstantMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {64.f}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {64.f}, {3.f}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}}
        }
    }
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::CONSTANT),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForConstantMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForConstantMode

// dequantization with "CONSTANT" mode (non zero value) and non unique pad dimension: dequantization isn't propagated
namespace testCasesForConstantModeWithNonZeroValues {
const std::vector<PadTransformationTestValues> testValuesForConstantMode2 = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    }
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::CONSTANT),
        ::testing::Values(1.f),
        ::testing::ValuesIn(testValuesForConstantMode2)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForConstantModeWithNonZeroValues

namespace testCasesForConstantModeAndUniquePadDimension {
const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> padsByUniqueDimension = {
    {0, 0, 2, 0},
    {0, 0, 1, 0}
};

const std::vector<PadTransformationTestValues> testValuesForConstantMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{64.f, 64.f, 64.f, 32.f, 32.f, 32.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{3.f, 3.f, 3.f, 2.f, 2.f, 2.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{0.f, 0.f, 64.f, 64.f, 64.f, 32.f, 32.f, 32.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {{1.f, 1.f, 3.f, 3.f, 3.f, 2.f, 2.f, 2.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {64.f},
                {3.f}
            }
        },
        {
            ngraph::element::i8,
            {},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{0.f, 0.f, 64.f, 64.f, 64.f, 64.f, 64.f, 64.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {3.f}
            }
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsByUniqueDimension),
        ::testing::Values(ngraph::op::PadMode::CONSTANT),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForConstantMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForConstantModeAndUniquePadDimension

namespace testCasesForNonZeroConstantModeAndUniquePadDimension {
const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> padsByUniqueDimension = {
    {0, 0, 2, 0},
    {0, 0, 1, 0}
};

const std::vector<PadTransformationTestValues> testValuesForConstantMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {},
                {{3.f, 3.f, 3.f, 2.f, 2.f, 2.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {},
                {{1.f, 1.f, 3.f, 3.f, 3.f, 2.f, 2.f, 2.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {64.f},
                {3.f}
            }
        },
        {
            ngraph::element::i8,
            {},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{0.f, 0.f, 64.f, 64.f, 64.f, 64.f, 64.f, 64.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {{1.f, 1.f, 3.f, 3.f, 3.f, 3.f, 3.f, 3.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsByUniqueDimension),
        ::testing::Values(ngraph::op::PadMode::CONSTANT),
        ::testing::Values(2.f),
        ::testing::ValuesIn(testValuesForConstantMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForNonZeroConstantModeAndUniquePadDimension

namespace testCasesForEdgeMode {
const std::vector<PadTransformationTestValues> testValuesForEdgeMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::EDGE),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForEdgeMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForEdgeMode

namespace testCasesForReflectMode {
const std::vector<PadTransformationTestValues> testValuesForReflectMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
            },
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::REFLECT),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForReflectMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForReflectMode

namespace testCasesForSymetricMode {
const std::vector<PadTransformationTestValues> testValuesForSymetricMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{2.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {{2.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::SYMMETRIC),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForSymetricMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForSymetricMode

namespace testCasesWithDynamicChannels {
const std::vector<ngraph::PartialShape> inputShapesWithDynamicChannels = {
    {Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()}
};

std::vector<ngraph::op::PadMode> allModes = {
    ngraph::op::PadMode::EDGE,
    ngraph::op::PadMode::REFLECT,
    ngraph::op::PadMode::SYMMETRIC,
    ngraph::op::PadMode::CONSTANT,
};

const std::vector<PadTransformationTestValues> testValuesForDynamicChannels = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}},
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapesWithDynamicChannels),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::ValuesIn(allModes),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForDynamicChannels)),
    PadTransformation::getTestCaseName);
} // namespace testCasesWithDynamicChannels

namespace testCasesWithDynamicRank {
const std::vector<ngraph::PartialShape> inputShapesWithDynamicRank = {
    ngraph::PartialShape::dynamic()
};

std::vector<ngraph::op::PadMode> allModes = {
    ngraph::op::PadMode::EDGE,
    ngraph::op::PadMode::REFLECT,
    ngraph::op::PadMode::SYMMETRIC,
    ngraph::op::PadMode::CONSTANT,
};

const std::vector<PadTransformationTestValues> testValuesForDynamicRank = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}},
            ngraph::element::f32,
            {{}, {}, {}},
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}},
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapesWithDynamicRank),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::ValuesIn(allModes),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForDynamicRank)),
    PadTransformation::getTestCaseName);
} // namespace testCasesWithDynamicRank
} // namespace


{
    actualFunction->validate_nodes_and_infer_types();
    auto res = compare_functions(referenceFunction, actualFunction, true, true);
    ASSERT_TRUE(res.first) << res.second;

    ASSERT_TRUE(LayerTransformation::allNamesAreUnique(actualFunction)) << "Not all names are unique";
}

#include "layer_transformation.hpp"

#include <string>
#include <sstream>
#include <gtest/gtest.h>
#include <ngraph/ngraph.hpp>

#include <low_precision/pad.hpp>

#include "common_test_utils/ngraph_test_utils.hpp"
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
#include "lpt_ngraph_functions/pad_function.hpp"
#include "simple_low_precision_transformer.hpp"

namespace {
using namespace testing;
using namespace ngraph;
using namespace ngraph::pass;

class PadTransformationTestValues {
public:
    class Actual {
    public:
        ngraph::element::Type precisionBeforeDequantization;
        ngraph::builder::subgraph::DequantizationOperations dequantization;
    };

    class Expected {
    public:
        ngraph::element::Type precisionBeforeDequantization;
        ngraph::builder::subgraph::DequantizationOperations dequantizationBefore;
        ngraph::element::Type precisionAfterOperation;
        ngraph::builder::subgraph::DequantizationOperations dequantizationAfter;
    };

    TestTransformationParams params;
    Actual actual;
    Expected expected;
};

typedef std::tuple <
    ngraph::PartialShape, // input Shape
    std::pair<std::vector<uint64_t>, std::vector<uint64_t>>, // pads begin, pads end
    ngraph::op::PadMode, // pads mode
    float, // pads value (used if mode == CONSTANT)
    PadTransformationTestValues> PadTransformationParams;

class PadTransformation : public LayerTransformation, public testing::WithParamInterface<PadTransformationParams> {
public:
    void SetUp() override {
        const ngraph::PartialShape inputShape = std::get<0>(GetParam());
        const auto pads = std::get<1>(GetParam());
        const ngraph::op::PadMode padsMode = std::get<2>(GetParam());
        const float padsValue = std::get<3>(GetParam());
        const PadTransformationTestValues testValues = std::get<4>(GetParam());

        const auto precisionAfterActualOp = testValues.actual.dequantization.convert.empty() ?
            testValues.actual.precisionBeforeDequantization : testValues.actual.dequantization.convert.outPrecision;

        actualFunction = ngraph::builder::subgraph::PadFunction::get(
            inputShape,
            testValues.actual.precisionBeforeDequantization,
            testValues.actual.dequantization,
            pads.first,
            pads.second,
            padsMode,
            padsValue,
            precisionAfterActualOp,
            { {}, {}, {} });

        SimpleLowPrecisionTransformer transformer;
        transformer.add<ngraph::pass::low_precision::PadTransformation, ngraph::opset1::Pad>(testValues.params);
        transformer.transform(actualFunction);

        referenceFunction = ngraph::builder::subgraph::PadFunction::get(
            inputShape,
            testValues.expected.precisionBeforeDequantization,
            testValues.expected.dequantizationBefore,
            pads.first,
            pads.second,
            padsMode,
            padsValue,
            testValues.expected.precisionAfterOperation,
            testValues.expected.dequantizationAfter);
    }

    static std::string getTestCaseName(testing::TestParamInfo<PadTransformationParams> obj) {
        const ngraph::PartialShape inputShape = std::get<0>(obj.param);
        const auto pads = std::get<1>(obj.param);
        const ngraph::op::PadMode padsMode = std::get<2>(obj.param);
        const float padsValue = std::get<3>(obj.param);
        const PadTransformationTestValues testValues = std::get<4>(obj.param);

        std::ostringstream result;
        result << "mode_" << padsMode << "_";
        if (padsMode == ngraph::op::PadMode::CONSTANT) {
            result << "pad_value_{ " << padsValue << " }";
        }

        result << "_" <<
            toString(testValues.params) << "_" <<
            inputShape << "_" << pads.first << "_" << pads.second << "_" <<
            testValues.actual.precisionBeforeDequantization << "_" <<
            testValues.actual.dequantization << "_" <<
            testValues.expected.dequantizationBefore;

        return result.str();
    }
};

TEST_P(PadTransformation, CompareFunctions)

const std::vector<ngraph::PartialShape> inputShapes = {
    {1, 3, 6, 6},
    {4, 3, 6, 6},
    {Dimension::dynamic(), 3, 6, Dimension::dynamic()}
};

const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> padsBySpatialDimensions = {
    {0, 0, 2, 1},
    {0, 0, 1, 2}
};

// test-cases with common logic for all modes
// (per-tensor & per-channel quantizations without subtracts, pads by spatial dimensions)
// and test-case without dequantization
namespace commonTestCases {
std::vector<ngraph::op::PadMode> allModes = {
    ngraph::op::PadMode::EDGE,
    ngraph::op::PadMode::REFLECT,
    ngraph::op::PadMode::SYMMETRIC,
    ngraph::op::PadMode::CONSTANT,
};

const std::vector<PadTransformationTestValues> deqWithoutSub = {
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{}, {}, {}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::f32,
            {{}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::f32,
            {{}, {}, {}},
            ngraph::element::f32,
            {{}, {}, {{3.f, 1.f, 2.f}}}
        }
    },
    {
        LayerTransformation::createParamsU8I8().setUpdatePrecisions(false),
        {
            ngraph::element::f32,
            {{}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::f32,
            {{}, {}, {}},
            ngraph::element::f32,
            {{}, {}, {{3.f, 1.f, 2.f}}}
        }
    }
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::ValuesIn(allModes),
        ::testing::Values(0.f),
        ::testing::ValuesIn(deqWithoutSub)),
    PadTransformation::getTestCaseName);
} // namespace commonTestCases

// test-cases with common logic for "EDGE", "REFLECT", and "SYMMETRIC" modes:
// pads by spatial dimensions, dequantization with subtract
namespace dqWithSubtract {
std::vector<ngraph::op::PadMode> modesInWhichSubPropagated = {
    ngraph::op::PadMode::EDGE,
    ngraph::op::PadMode::REFLECT,
    ngraph::op::PadMode::SYMMETRIC,
};

const std::vector<PadTransformationTestValues> deqWithSub = {
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {128.f}, {3.f}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {128.f}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {64.f}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {64.f}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}}
        }
    }
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::ValuesIn(modesInWhichSubPropagated),
        ::testing::Values(0.f),
        ::testing::ValuesIn(deqWithSub)),
    PadTransformation::getTestCaseName);
} // namespace dqWithSubtract

// dequantization with subtract and "CONSTANT" mode, also dequantization and padding by the same dimension
namespace testCasesForConstantMode {
const std::vector<PadTransformationTestValues> testValuesForConstantMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {64.f}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {64.f}, {3.f}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}}
        }
    }
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::CONSTANT),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForConstantMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForConstantMode

// dequantization with "CONSTANT" mode (non zero value) and non unique pad dimension: dequantization isn't propagated
namespace testCasesForConstantModeWithNonZeroValues {
const std::vector<PadTransformationTestValues> testValuesForConstantMode2 = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    }
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::CONSTANT),
        ::testing::Values(1.f),
        ::testing::ValuesIn(testValuesForConstantMode2)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForConstantModeWithNonZeroValues

namespace testCasesForConstantModeAndUniquePadDimension {
const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> padsByUniqueDimension = {
    {0, 0, 2, 0},
    {0, 0, 1, 0}
};

const std::vector<PadTransformationTestValues> testValuesForConstantMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{64.f, 64.f, 64.f, 32.f, 32.f, 32.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{3.f, 3.f, 3.f, 2.f, 2.f, 2.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{0.f, 0.f, 64.f, 64.f, 64.f, 32.f, 32.f, 32.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {{1.f, 1.f, 3.f, 3.f, 3.f, 2.f, 2.f, 2.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {64.f},
                {3.f}
            }
        },
        {
            ngraph::element::i8,
            {},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{0.f, 0.f, 64.f, 64.f, 64.f, 64.f, 64.f, 64.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {3.f}
            }
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsByUniqueDimension),
        ::testing::Values(ngraph::op::PadMode::CONSTANT),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForConstantMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForConstantModeAndUniquePadDimension

namespace testCasesForNonZeroConstantModeAndUniquePadDimension {
const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> padsByUniqueDimension = {
    {0, 0, 2, 0},
    {0, 0, 1, 0}
};

const std::vector<PadTransformationTestValues> testValuesForConstantMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {},
                {{3.f, 3.f, 3.f, 2.f, 2.f, 2.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {},
                {{1.f, 1.f, 3.f, 3.f, 3.f, 2.f, 2.f, 2.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {64.f},
                {3.f}
            }
        },
        {
            ngraph::element::i8,
            {},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{0.f, 0.f, 64.f, 64.f, 64.f, 64.f, 64.f, 64.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {{1.f, 1.f, 3.f, 3.f, 3.f, 3.f, 3.f, 3.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsByUniqueDimension),
        ::testing::Values(ngraph::op::PadMode::CONSTANT),
        ::testing::Values(2.f),
        ::testing::ValuesIn(testValuesForConstantMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForNonZeroConstantModeAndUniquePadDimension

namespace testCasesForEdgeMode {
const std::vector<PadTransformationTestValues> testValuesForEdgeMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::EDGE),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForEdgeMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForEdgeMode

namespace testCasesForReflectMode {
const std::vector<PadTransformationTestValues> testValuesForReflectMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
            },
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::REFLECT),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForReflectMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForReflectMode

namespace testCasesForSymetricMode {
const std::vector<PadTransformationTestValues> testValuesForSymetricMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{2.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {{2.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::SYMMETRIC),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForSymetricMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForSymetricMode

namespace testCasesWithDynamicChannels {
const std::vector<ngraph::PartialShape> inputShapesWithDynamicChannels = {
    {Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()}
};

std::vector<ngraph::op::PadMode> allModes = {
    ngraph::op::PadMode::EDGE,
    ngraph::op::PadMode::REFLECT,
    ngraph::op::PadMode::SYMMETRIC,
    ngraph::op::PadMode::CONSTANT,
};

const std::vector<PadTransformationTestValues> testValuesForDynamicChannels = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}},
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapesWithDynamicChannels),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::ValuesIn(allModes),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForDynamicChannels)),
    PadTransformation::getTestCaseName);
} // namespace testCasesWithDynamicChannels

namespace testCasesWithDynamicRank {
const std::vector<ngraph::PartialShape> inputShapesWithDynamicRank = {
    ngraph::PartialShape::dynamic()
};

std::vector<ngraph::op::PadMode> allModes = {
    ngraph::op::PadMode::EDGE,
    ngraph::op::PadMode::REFLECT,
    ngraph::op::PadMode::SYMMETRIC,
    ngraph::op::PadMode::CONSTANT,
};

const std::vector<PadTransformationTestValues> testValuesForDynamicRank = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}},
            ngraph::element::f32,
            {{}, {}, {}},
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}},
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapesWithDynamicRank),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::ValuesIn(allModes),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForDynamicRank)),
    PadTransformation::getTestCaseName);
} // namespace testCasesWithDynamicRank
} // namespace


#include "layer_transformation.hpp"

#include <string>
#include <sstream>
#include <gtest/gtest.h>
#include <ngraph/ngraph.hpp>

#include <low_precision/pad.hpp>

#include "common_test_utils/ngraph_test_utils.hpp"
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
#include "lpt_ngraph_functions/pad_function.hpp"
#include "simple_low_precision_transformer.hpp"

namespace {
using namespace testing;
using namespace ngraph;
using namespace ngraph::pass;

class PadTransformationTestValues {
public:
    class Actual {
    public:
        ngraph::element::Type precisionBeforeDequantization;
        ngraph::builder::subgraph::DequantizationOperations dequantization;
    };

    class Expected {
    public:
        ngraph::element::Type precisionBeforeDequantization;
        ngraph::builder::subgraph::DequantizationOperations dequantizationBefore;
        ngraph::element::Type precisionAfterOperation;
        ngraph::builder::subgraph::DequantizationOperations dequantizationAfter;
    };

    TestTransformationParams params;
    Actual actual;
    Expected expected;
};

typedef std::tuple <
    ngraph::PartialShape, // input Shape
    std::pair<std::vector<uint64_t>, std::vector<uint64_t>>, // pads begin, pads end
    ngraph::op::PadMode, // pads mode
    float, // pads value (used if mode == CONSTANT)
    PadTransformationTestValues> PadTransformationParams;

class PadTransformation : public LayerTransformation, public testing::WithParamInterface<PadTransformationParams> {
public:
    void SetUp() override {
        const ngraph::PartialShape inputShape = std::get<0>(GetParam());
        const auto pads = std::get<1>(GetParam());
        const ngraph::op::PadMode padsMode = std::get<2>(GetParam());
        const float padsValue = std::get<3>(GetParam());
        const PadTransformationTestValues t

        const auto precisionAfterActualOp = testValues.actual.dequantization.convert.empty() ?
            testValues.actual.precisionBeforeDequantization : testValues.actual.dequantization.convert.outPrecision;

        actualFunction = ngraph::builder::subgraph::PadFunction::get(
            inputShape,
            testValues.actual.precisionBeforeDequantization,
            testValues.actual.dequantization,
            pads.first,
            pads.second,
            padsMode,
            padsValue,
            precisionAfterActualOp,
            { {}, {}, {} });

        SimpleLowPrecisionTransformer transformer;
        transformer.add<ngraph::pass::low_precision::PadTransformation, ngraph::opset1::Pad>(testValues.params);
        transformer.transform(actualFunction);

        referenceFunction = ngraph::builder::subgraph::PadFunction::get(
            inputShape,
            testValues.expected.precisionBeforeDequantization,
            testValues.expected.dequantizationBefore,
            pads.first,
            pads.second,
            padsMode,
            padsValue,
            testValues.expected.precisionAfterOperation,
            testValues.expected.dequantizationAfter);
    }

    static std::string getTestCaseName(testing::TestParamInfo<PadTransformationParams> obj) {
        const ngraph::PartialShape inputShape = std::get<0>(obj.param);
        const auto pads = std::get<1>(obj.param);
        const ngraph::op::PadMode padsMode = std::get<2>(obj.param);
        const float padsValue = std::get<3>(obj.param);
        const PadTransformationTestValues testValues = std::get<4>(obj.param);

        std::ostringstream result;
        result << "mode_" << padsMode << "_";
        if (padsMode == ngraph::op::PadMode::CONSTANT) {
            result << "pad_value_{ " << padsValue << " }";
        }

        result << "_" <<
            toString(testValues.params) << "_" <<
            inputShape << "_" << pads.first << "_" << pads.second << "_" <<
            testValues.actual.precisionBeforeDequantization << "_" <<
            testValues.actual.dequantization << "_" <<
            testValues.expected.dequantizationBefore;

        return result.str();
    }
};

TEST_P(PadTransformation, CompareFunctions) {
    actualFunction->validate_nodes_and_infer_types();
    auto res = compare_functions(referenceFunction, actualFunction, true, true);
    ASSERT_TRUE(res.first) << res.second;

    ASSERT_TRUE(LayerTransformation::allNamesAreUnique(actualFunction)) << "Not all names are unique";
}

const std::vector<ngraph::PartialShape> inputShapes = {
    {1, 3, 6, 6},
    {4, 3, 6, 6},
    {Dimension::dynamic(), 3, 6, Dimension::dynamic()}
};

const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> padsBySpatialDimensions = {
    {0, 0, 2, 1},
    {0, 0, 1, 2}
};

// test-cases with common logic for all modes
// (per-tensor & per-channel quantizations without subtracts, pads by spatial dimensions)
// and test-case without dequantization
namespace commonTestCases {
std::vector<ngraph::op::PadMode> allModes = {
    ngraph::op::PadMode::EDGE,
    ngraph::op::PadMode::REFLECT,
    ngraph::op::PadMode::SYMMETRIC,
    ngraph::op::PadMode::CONSTANT,
};

const std::vector<PadTransformationTestValues> deqWithoutSub = {
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{}, {}, {}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::f32,
            {{}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::f32,
            {{}, {}, {}},
            ngraph::element::f32,
            {{}, {}, {{3.f, 1.f, 2.f}}}
        }
    },
    {
        LayerTransformation::createParamsU8I8().setUpdatePrecisions(false),
        {
            ngraph::element::f32,
            {{}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::f32,
            {{}, {}, {}},
            ngraph::element::f32,
            {{}, {}, {{3.f, 1.f, 2.f}}}
        }
    }
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::ValuesIn(allModes),
        ::testing::Values(0.f),
        ::testing::ValuesIn(deqWithoutSub)),
    PadTransformation::getTestCaseName);
} // namespace commonTestCases

// test-cases with common logic for "EDGE", "REFLECT", and "SYMMETRIC" modes:
// pads by spatial dimensions, dequantization with subtract
namespace dqWithSubtract {
std::vector<ngraph::op::PadMode> modesInWhichSubPropagated = {
    ngraph::op::PadMode::EDGE,
    ngraph::op::PadMode::REFLECT,
    ngraph::op::PadMode::SYMMETRIC,
};

const std::vector<PadTransformationTestValues> deqWithSub = {
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {128.f}, {3.f}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {128.f}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {64.f}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {64.f}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}}
        }
    }
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::ValuesIn(modesInWhichSubPropagated),
        ::testing::Values(0.f),
        ::testing::ValuesIn(deqWithSub)),
    PadTransformation::getTestCaseName);
} // namespace dqWithSubtract

// dequantization with subtract and "CONSTANT" mode, also dequantization and padding by the same dimension
namespace testCasesForConstantMode {
const std::vector<PadTransformationTestValues> testValuesForConstantMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {64.f}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {64.f}, {3.f}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}}
        },
        {
            ngraph::element::u8,
            {{}, {}, {}},
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}}
        }
    }
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::CONSTANT),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForConstantMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForConstantMode

// dequantization with "CONSTANT" mode (non zero value) and non unique pad dimension: dequantization isn't propagated
namespace testCasesForConstantModeWithNonZeroValues {
const std::vector<PadTransformationTestValues> testValuesForConstantMode2 = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
    {
        LayerTransformation::createParamsU8I8(),
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::u8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}}
        }
    }
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::CONSTANT),
        ::testing::Values(1.f),
        ::testing::ValuesIn(testValuesForConstantMode2)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForConstantModeWithNonZeroValues

namespace testCasesForConstantModeAndUniquePadDimension {
const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> padsByUniqueDimension = {
    {0, 0, 2, 0},
    {0, 0, 1, 0}
};

const std::vector<PadTransformationTestValues> testValuesForConstantMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{64.f, 64.f, 64.f, 32.f, 32.f, 32.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{3.f, 3.f, 3.f, 2.f, 2.f, 2.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{0.f, 0.f, 64.f, 64.f, 64.f, 32.f, 32.f, 32.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {{1.f, 1.f, 3.f, 3.f, 3.f, 2.f, 2.f, 2.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {64.f},
                {3.f}
            }
        },
        {
            ngraph::element::i8,
            {},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{0.f, 0.f, 64.f, 64.f, 64.f, 64.f, 64.f, 64.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {3.f}
            }
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsByUniqueDimension),
        ::testing::Values(ngraph::op::PadMode::CONSTANT),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForConstantMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForConstantModeAndUniquePadDimension

namespace testCasesForNonZeroConstantModeAndUniquePadDimension {
const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> padsByUniqueDimension = {
    {0, 0, 2, 0},
    {0, 0, 1, 0}
};

const std::vector<PadTransformationTestValues> testValuesForConstantMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {},
                {{3.f, 3.f, 3.f, 2.f, 2.f, 2.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {},
                {{1.f, 1.f, 3.f, 3.f, 3.f, 2.f, 2.f, 2.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {64.f},
                {3.f}
            }
        },
        {
            ngraph::element::i8,
            {},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{0.f, 0.f, 64.f, 64.f, 64.f, 64.f, 64.f, 64.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {{1.f, 1.f, 3.f, 3.f, 3.f, 3.f, 3.f, 3.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsByUniqueDimension),
        ::testing::Values(ngraph::op::PadMode::CONSTANT),
        ::testing::Values(2.f),
        ::testing::ValuesIn(testValuesForConstantMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForNonZeroConstantModeAndUniquePadDimension

namespace testCasesForEdgeMode {
const std::vector<PadTransformationTestValues> testValuesForEdgeMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::EDGE),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForEdgeMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForEdgeMode

namespace testCasesForReflectMode {
const std::vector<PadTransformationTestValues> testValuesForReflectMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
            },
            ngraph::element::f32,
            {{}, {}, {}}
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::REFLECT),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForReflectMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForReflectMode

namespace testCasesForSymetricMode {
const std::vector<PadTransformationTestValues> testValuesForSymetricMode = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
                {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
            }
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {
                {ngraph::element::f32},
                {{2.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}},
                {{2.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}}
            }
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapes),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::Values(ngraph::op::PadMode::SYMMETRIC),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForSymetricMode)),
    PadTransformation::getTestCaseName);
} // namespace testCasesForSymetricMode

namespace testCasesWithDynamicChannels {
const std::vector<ngraph::PartialShape> inputShapesWithDynamicChannels = {
    {Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()}
};

std::vector<ngraph::op::PadMode> allModes = {
    ngraph::op::PadMode::EDGE,
    ngraph::op::PadMode::REFLECT,
    ngraph::op::PadMode::SYMMETRIC,
    ngraph::op::PadMode::CONSTANT,
};

const std::vector<PadTransformationTestValues> testValuesForDynamicChannels = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{}, {}, {}},
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}},
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapesWithDynamicChannels),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::ValuesIn(allModes),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForDynamicChannels)),
    PadTransformation::getTestCaseName);
} // namespace testCasesWithDynamicChannels

namespace testCasesWithDynamicRank {
const std::vector<ngraph::PartialShape> inputShapesWithDynamicRank = {
    ngraph::PartialShape::dynamic()
};

std::vector<ngraph::op::PadMode> allModes = {
    ngraph::op::PadMode::EDGE,
    ngraph::op::PadMode::REFLECT,
    ngraph::op::PadMode::SYMMETRIC,
    ngraph::op::PadMode::CONSTANT,
};

const std::vector<PadTransformationTestValues> testValuesForDynamicRank = {
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {3.f}},
            ngraph::element::f32,
            {{}, {}, {}},
        }
    },
    {
        LayerTransformation::createParamsI8I8(),
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
        },
        {
            ngraph::element::i8,
            {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
            ngraph::element::f32,
            {{}, {}, {}},
        }
    },
};

INSTANTIATE_TEST_SUITE_P(
    smoke_LPT,
    PadTransformation,
    ::testing::Combine(
        ::testing::ValuesIn(inputShapesWithDynamicRank),
        ::testing::Values(padsBySpatialDimensions),
        ::testing::ValuesIn(allModes),
        ::testing::Values(0.f),
        ::testing::ValuesIn(testValuesForDynamicRank)),
    PadTransformation::getTestCaseName);
} // namespace testCasesWithDynamicRank
} // namespace