diff --git a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/base/ov_subgraph.hpp b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/base/ov_subgraph.hpp new file mode 100644 index 00000000000..9ec3cc83965 --- /dev/null +++ b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/base/ov_subgraph.hpp @@ -0,0 +1,117 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include "common_test_utils/ngraph_test_utils.hpp" +#include "common_test_utils/common_utils.hpp" +#include "common_test_utils/test_common.hpp" +#include "common_test_utils/test_constants.hpp" + +#include "functional_test_utils/skip_tests_config.hpp" +#include "functional_test_utils/ov_plugin_cache.hpp" +//#include "functional_test_utils/ov_tensor_utils.hpp" +#include "functional_test_utils/precision_utils.hpp" +#include "functional_test_utils/layer_test_utils/summary.hpp" +#include "functional_test_utils/layer_test_utils/environment.hpp" + +#include "ngraph_functions/utils/ngraph_helpers.hpp" +#include "ngraph_functions/pass/convert_prc.hpp" + +namespace ov { +namespace test { + +class SubgraphBaseTest : public CommonTestUtils::TestsCommon { +public: + virtual void run(); + virtual void serialize(); + virtual void query_model(); + + void TearDown() override { + if (!configuration.empty()) { + ov::test::PluginCache::get().core().reset(); + } + } + +protected: + void compare(const std::vector &expected, + const std::vector &actual); + +// virtual void compare_desc(const ov::runtime::Tensor &expected, const ov::runtime::Tensor &actual); + +// std::shared_ptr get_function(); + +// std::map &get_configuration(); + +// std::string get_runtime_precision(const std::string &layerName); + +// std::string get_runtime_precision_by_type(const std::string &layerType); + +//#ifndef NDEBUG +// +// void show_runtime_precision(); +// +//#endif + +// virtual void configure_model(); + + virtual void compile_model(); +// + virtual void generate_inputs(const std::vector& targetInputStaticShapes); +// + virtual void infer(); +// + virtual void validate(); +// + +// +// virtual std::vector get_outputs(); + + std::shared_ptr core = ov::test::PluginCache::get().core(); + std::string targetDevice; + std::map configuration; + + std::shared_ptr function; + std::shared_ptr functionRefs; + ov::element::Type inPrc; + ov::element::Type outPrc; + std::map inputs; + std::vector inputDynamicShapes; + std::vector> targetStaticShapes; + + ov::runtime::ExecutableNetwork executableNetwork; + ov::runtime::InferRequest inferRequest; + + constexpr static const auto disable_treshold = std::numeric_limits::max(); + double abs_threshold = disable_treshold; + double rel_threshold = disable_treshold; + + LayerTestsUtils::Summary& summary = LayerTestsUtils::Summary::getInstance();; + +private: +// ov::runtime::Tensor generate_input(const ov::HostTensor &type, const ov::Shape &shape) const; + +// void compare(const std::pair> &expected, +// const ov::runtime::Tensor &actual); + void resize_ngraph_function(const std::vector& targetInputStaticShapes); + std::vector calculate_refs(); + std::vector get_outputs(); +}; +} // namespace test +} // namespace ov \ No newline at end of file diff --git a/inference-engine/tests/functional/shared_test_classes/src/base/ov_subgraph.cpp b/inference-engine/tests/functional/shared_test_classes/src/base/ov_subgraph.cpp new file mode 100644 index 00000000000..f3e2cfa5538 --- /dev/null +++ b/inference-engine/tests/functional/shared_test_classes/src/base/ov_subgraph.cpp @@ -0,0 +1,307 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#ifdef _WIN32 +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "openvino/core/variant.hpp" +#include "shared_test_classes/base/ov_subgraph.hpp" + +namespace ov { +namespace test { + +void SubgraphBaseTest::run() { + auto crashHandler = [](int errCode) { + auto &s = LayerTestsUtils::Summary::getInstance(); + s.saveReport(); + std::cerr << "Unexpected application crash with code: " << errCode << std::endl; + std::abort(); + }; + signal(SIGSEGV, crashHandler); + + LayerTestsUtils::PassRate::Statuses status = + FuncTestUtils::SkipTestsConfig::currentTestIsDisabled() ? + LayerTestsUtils::PassRate::Statuses::SKIPPED : LayerTestsUtils::PassRate::Statuses::CRASHED; + summary.setDeviceName(targetDevice); + summary.updateOPsStats(function, status); + SKIP_IF_CURRENT_TEST_IS_DISABLED(); + + OPENVINO_ASSERT(targetStaticShapes.empty(), "Target Static Shape is empty!!!"); + std::string errorMessage; + try { + compile_model(); + for (const auto& targetStaticShapeVec : targetStaticShapes) { + try { + if (!inputDynamicShapes.empty()) { + // resize ngraph function according new target shape + resize_ngraph_function(targetStaticShapeVec); + } + generate_inputs(targetStaticShapeVec); + infer(); + validate(); + status = LayerTestsUtils::PassRate::Statuses::PASSED; + } catch (const std::exception &ex) { +// OPENVINO_ASSERT("Incorrect target static shape: ", CommonTestUtils::vec2str(targetStaticShape), std::endl, ex.what()); + } + } + } catch (const std::exception &ex) { + status = LayerTestsUtils::PassRate::Statuses::FAILED; + errorMessage = ex.what(); + } catch (...) { + status = LayerTestsUtils::PassRate::Statuses::FAILED; + errorMessage = "Unknown failure occurred."; + } + summary.updateOPsStats(function, status); + GTEST_FATAL_FAILURE_(errorMessage.c_str()); +} + +void SubgraphBaseTest::serialize() { + SKIP_IF_CURRENT_TEST_IS_DISABLED(); + + std::string output_name = GetTestName().substr(0, CommonTestUtils::maxFileNameLength) + "_" + GetTimestamp(); + + std::string out_xml_path = output_name + ".xml"; + std::string out_bin_path = output_name + ".bin"; + + ngraph::pass::Manager manager; + manager.register_pass(out_xml_path, out_bin_path); + manager.run_passes(function); + function->validate_nodes_and_infer_types(); + + auto result = core->read_model(out_xml_path, out_bin_path); + + bool success; + std::string message; + std::tie(success, message) = + compare_functions(result, function, false, false, false, + true, // precision + true); // attributes + + EXPECT_TRUE(success) << message; + + CommonTestUtils::removeIRFiles(out_xml_path, out_bin_path); +} + +void SubgraphBaseTest::query_model() { + SKIP_IF_CURRENT_TEST_IS_DISABLED(); + + auto queryNetworkResult = core->query_model(function, targetDevice); + std::set expected; + for (auto&& node : function->get_ops()) { + expected.insert(node->get_friendly_name()); + } + + std::set actual; + for (auto&& res : queryNetworkResult) { + actual.insert(res.first); + } + ASSERT_EQ(expected, actual); +} + +//ov::runtime::Tensor SubgraphBaseTest::generate_input(const element::Type& type, const ov::Shape& shape) const { +// return create_and_fill_tensor(type, shape); +//} +// +//void SubgraphBaseTest::compare(const std::vector>>& expectedOutputs, +// const std::vector& actualOutputs) { +// for (std::size_t outputIndex = 0; outputIndex < expectedOutputs.size(); ++outputIndex) { +// const auto& expected = expectedOutputs[outputIndex]; +// const auto& actual = actualOutputs[outputIndex]; +// compare(expected, actual); +// } +//} +// +//void SubgraphBaseTest::compare(const std::pair>& expected, +// const ov::runtime::Tensor& actual) { +void SubgraphBaseTest::compare(const std::vector &expected, + const std::vector &actual) { + ASSERT_EQ(expected.size(), actual.size()); + for (size_t i = 0; i < expected.size(); i++) { + ov::test::utils::compare(expected[i], actual[i], abs_threshold, rel_threshold); + } +// return ::ov::test::utils::compare(expected_tensor, actual, abs_threshold, rel_threshold); +} + +//void SubgraphBaseTest::compare_desc(const ov::runtime::Tensor& expected, const ov::runtime::Tensor& actual) { +// ASSERT_EQ(expected.get_element_type(), actual.get_element_type()); +// ASSERT_EQ(expected.get_shape(), actual.get_shape()); +//} + +//void SubgraphBaseTest::configure_model() { +// // configure input precision +// { +// auto params = function->get_parameters(); +// for (auto& param : params) { +// param->get_output_tensor(0).set_element_type(inPrc); +// } +// } +// +// // configure output precision +// { +// auto results = function->get_results(); +// for (auto& result : results) { +// result->get_output_tensor(0).set_element_type(outPrc); +// } +// } +//} + +void SubgraphBaseTest::compile_model() { +// configure_model(); + executableNetwork = core->compile_model(function, targetDevice, configuration); +} + +void SubgraphBaseTest::generate_inputs(const std::vector& targetInputStaticShapes) { + inputs.clear(); + const auto& params = function->get_parameters(); + for (int i = 0; i < params.size(); ++i) { + const auto& param = params[i]; + ov::runtime::Tensor tensor = ov::test::utils::create_and_fill_tensor(param->get_element_type(), targetInputStaticShapes[i]); + inputs.insert({param->get_friendly_name(), tensor}); + } +} + +void SubgraphBaseTest::infer() { + inferRequest = executableNetwork.create_infer_request(); + for (const auto& input : inputs) { + inferRequest.set_tensor(input.first, input.second); + } + inferRequest.infer(); +} +// +std::vector SubgraphBaseTest::calculate_refs() { + // nGraph interpreter does not support f16/bf16 + ngraph::pass::ConvertPrecision().run_on_function(function); + ngraph::pass::ConvertPrecision().run_on_function(function); + + function->validate_nodes_and_infer_types(); + +// auto referenceInputs = std::vector>(inputs.size()); +// auto refInputsTypes = std::vector(inputs.size()); +// for (const auto& inputTensor : inputs) { +// const auto &input = inputTensor.second; +// const auto &inputSize = input.get_byte_size(); +// auto &referenceInput = referenceInputs[i]; +// referenceInput.resize(inputSize); +// const auto buffer = static_cast(input.data()); +// std::copy(buffer, buffer + inputSize, referenceInput.data()); +// refInputsTypes[i] = input.get_element_type(); +// } + auto referenceInputs = inputs; + +// auto expectedOutputs = ngraph::helpers::interpreterFunction(function, referenceInputs, refInputsTypes); + auto expectedOutputs = ngraph::helpers::interpreterFunction(function, referenceInputs); + return expectedOutputs; +} +// +std::vector SubgraphBaseTest::get_outputs() { + auto outputs = std::vector{}; + for (const auto& output : executableNetwork.get_results()) { + const auto& name = output->input_value(0).get_node()->get_friendly_name(); + outputs.push_back(inferRequest.get_tensor(name)); + } + return outputs; +} +// +void SubgraphBaseTest::validate() { + auto expectedOutputs = calculate_refs(); + const auto& actualOutputs = get_outputs(); + + if (expectedOutputs.empty()) { + return; + } + + OPENVINO_ASSERT(actualOutputs.size() == expectedOutputs.size(), + "nGraph interpreter has ", expectedOutputs.size(), " outputs, while IE ", actualOutputs.size()); + + compare(expectedOutputs, actualOutputs); +} + +//std::string SubgraphBaseTest::get_runtime_precision(const std::string& layerName) { +// const auto function = executableNetwork.get_runtime_function(); +// for (const auto& op : function->get_ops()) { +// const auto name = op->get_friendly_name(); +// if (name == layerName) { +// const auto& rtInfo = op->get_rt_info(); +// const auto& it = rtInfo.find("runtimePrecision"); +// +// OPENVINO_ASSERT(it != rtInfo.end(), "Runtime precision is not found for node: ", name); +// +// const auto rtPrecisionPtr = ngraph::as_type_ptr>(it->second); +// return rtPrecisionPtr->get(); +// } +// } +// return {}; +//} + +//std::string SubgraphBaseTest::get_runtime_precision_by_type(const std::string& layerType) { +// const auto function = executableNetwork.get_runtime_function(); +// +// for (const auto& op : function->get_ops()) { +// const auto& rtInfo = op->get_rt_info(); +// const auto& typeIt = rtInfo.find("layerType"); +// +// OPENVINO_ASSERT(typeIt != rtInfo.end(), "Layer is not found for type: ", layerType); +// +// const auto type = ngraph::as_type_ptr>(typeIt->second)->get(); +// if (type == layerType) { +// const auto& it = rtInfo.find("runtimePrecision"); +// +// OPENVINO_ASSERT(it != rtInfo.end(), "Runtime precision is not found for node: ", type); +// +// const auto rtPrecisionPtr = ngraph::as_type_ptr>(it->second); +// return rtPrecisionPtr->get(); +// } +// } +// +// return {}; +//} + +//#ifndef NDEBUG +//void SubgraphBaseTest::show_runtime_precision() { +// const auto function = executableNetwork.get_runtime_function(); +// +// for (const auto& op : function->get_ops()) { +// const auto& rtInfo = op->get_rt_info(); +// const auto& typeIt = rtInfo.find("layerType"); +// +// const auto type = ngraph::as_type_ptr>(typeIt->second)->get(); +// const auto& it = rtInfo.find("runtimePrecision"); +// +// const auto rtPrecisionPtr = ngraph::as_type_ptr>(it->second); +// std::cout << type << ": " << rtPrecisionPtr->get() << std::endl; +// } +//} +//#endif + +//std::shared_ptr SubgraphBaseTest::get_function() { +// return function; +//} +// +//std::map& SubgraphBaseTest::get_configuration() { +// return configuration; +//} + +void SubgraphBaseTest::resize_ngraph_function(const std::vector& targetInputStaticShapes) { + auto params = function->get_parameters(); + std::map shapes; + ASSERT_LE(params.size(), targetInputStaticShapes.size()); + for (size_t i = 0; i < params.size(); i++) { + shapes.insert({*params[i]->get_output_tensor(0).get_names().begin(), targetInputStaticShapes[i]}); + } + function->reshape(shapes); + functionRefs->reshape(shapes); +} + +} // namespace test +} // namespace ov \ No newline at end of file diff --git a/inference-engine/tests/functional/shared_test_classes/src/single_layer/softmax.cpp b/inference-engine/tests/functional/shared_test_classes/src/single_layer/softmax.cpp index 18a70004f94..84317ae48c3 100644 --- a/inference-engine/tests/functional/shared_test_classes/src/single_layer/softmax.cpp +++ b/inference-engine/tests/functional/shared_test_classes/src/single_layer/softmax.cpp @@ -20,8 +20,6 @@ std::string SoftMaxLayerTest::getTestCaseName(const testing::TestParamInfo::value_type>(), \ + shape_size(shape), \ + range, start_from, resolution, seed); break; + switch (element_type) { + CASE(ov::element::Type_t::boolean) + CASE(ov::element::Type_t::bf16) + CASE(ov::element::Type_t::f16) + CASE(ov::element::Type_t::f32) + CASE(ov::element::Type_t::f64) + CASE(ov::element::Type_t::i4) + CASE(ov::element::Type_t::i8) + CASE(ov::element::Type_t::i16) + CASE(ov::element::Type_t::i32) + CASE(ov::element::Type_t::i64) + CASE(ov::element::Type_t::u1) + CASE(ov::element::Type_t::u4) + CASE(ov::element::Type_t::u8) + CASE(ov::element::Type_t::u16) + CASE(ov::element::Type_t::u32) + CASE(ov::element::Type_t::u64) + default: OPENVINO_UNREACHABLE("Unsupported element type: ", element_type); + } +#undef CASE + return tensor; +} + +template +void compare( + const ov::runtime::Tensor& expected, + const ov::runtime::Tensor& actual, + const double abs_threshold_ = std::numeric_limits::max(), + const double rel_threshold_ = std::numeric_limits::max()) { + auto expected_shape = expected.get_shape(); + auto actual_shape = actual.get_shape(); + ASSERT_EQ(expected_shape, actual_shape); + ASSERT_NE(shape_size(actual_shape), 0); + auto expected_data = expected.data(); + auto actual_data = actual.data(); + double abs_threshold = abs_threshold_; + double rel_threshold = rel_threshold_; + if (abs_threshold == std::numeric_limits::max() && rel_threshold == std::numeric_limits::max()) { + if (sizeof(ExpectedT) == 1 || sizeof(ActualT) == 1) { + abs_threshold = 1.; + } else { + std::vector abs_values; + abs_values.reserve(shape_size(expected_shape)); + for (auto&& c : ngraph::CoordinateTransformBasic{expected_shape}) { + abs_values.push_back(std::fabs( + static_cast( + expected_data[std::inner_product(c.begin(), c.end(), expected.get_strides().begin(), 0)]))); + } + std::sort(abs_values.begin(), abs_values.end()); + double abs_median; + if (abs_values.size() % 2 == 0) { + abs_median = (abs_values.at(abs_values.size()/2) + abs_values.at(abs_values.size()/2 + 1))/2.; + } else { + abs_median = abs_values.at(abs_values.size()/2); + } + abs_threshold = 0.05 * abs_median; + if (std::is_integral::value) { + abs_threshold = std::ceil(abs_threshold); + } + } + } + OPENVINO_ASSERT((!std::isnan(abs_threshold) && !std::isnan(rel_threshold)), + "abs_threshold: ", abs_threshold, " rel_threshold: ", rel_threshold); + struct Error { + double max = 0.; + double mean = 0.; + Coordinate max_coordinate; + size_t count = 0; + } abs_error, rel_error; + auto less = [] (double a, double b) { + auto eps = std::numeric_limits::epsilon(); + return (b - a) > (std::fmax(std::fabs(a), std::fabs(b)) * eps); + }; + for (auto&& c : ngraph::CoordinateTransformBasic{expected_shape}) { + double expected_value = expected_data[std::inner_product(c.begin(), c.end(), expected.get_strides().begin(), 0)]; + double actual_value = actual_data[std::inner_product(c.begin(), c.end(), actual.get_strides().begin(), 0)]; + auto error = [&] (Error& err, double val, double threshold) { + if (less(err.max, val)) { + err.max = val; + err.max_coordinate = c; + } + err.mean += val; + err.count += less(threshold, val); + }; + OPENVINO_ASSERT(!std::isnan(expected_value), "Expected value is NAN on coordinate: ", c); + OPENVINO_ASSERT(!std::isnan(actual_value), "Actual value is NAN on coordinate: ", c); + auto abs = std::fabs(expected_value - actual_value); + auto rel = expected_value ? (abs/std::fabs(expected_value)) : abs; + error(abs_error, abs, abs_threshold); + error(rel_error, rel, rel_threshold); + } + abs_error.mean /= shape_size(expected_shape); + rel_error.mean /= shape_size(expected_shape); + OPENVINO_ASSERT((less(abs_error.max, abs_threshold) && less(rel_error.max, rel_threshold)), + "abs_max < abs_threshold && rel_max < rel_threshold", + "\n\t abs_max: " , abs_error.max, + "\n\t\t coordinate " , abs_error.max_coordinate, + "; abs errors count " , abs_error.count , "; abs mean ", + abs_error.mean , "; abs threshold " , abs_threshold, + "\n\t rel_max: " , rel_error.max, + "\n\t\t coordinate " , rel_error.max_coordinate, + "; rel errors count " , rel_error.count , "; rel mean ", + rel_error.mean , "; rel threshold " , rel_threshold); +} + +void compare( + const ov::runtime::Tensor& expected, + const ov::runtime::Tensor& actual, + const double abs_threshold, + const double rel_threshold) { +#define CASE0(X, Y) case Y : compare< \ + element_type_traits::value_type, \ + element_type_traits::value_type>( \ + expected, actual, abs_threshold, rel_threshold); break; + +#define CASE(X) \ + case X: \ + switch (actual.get_element_type()) { \ + CASE0(X, ov::element::Type_t::boolean) \ + CASE0(X, ov::element::Type_t::bf16) \ + CASE0(X, ov::element::Type_t::f16) \ + CASE0(X, ov::element::Type_t::f32) \ + CASE0(X, ov::element::Type_t::f64) \ + CASE0(X, ov::element::Type_t::i4) \ + CASE0(X, ov::element::Type_t::i8) \ + CASE0(X, ov::element::Type_t::i16) \ + CASE0(X, ov::element::Type_t::i32) \ + CASE0(X, ov::element::Type_t::i64) \ + CASE0(X, ov::element::Type_t::u1) \ + CASE0(X, ov::element::Type_t::u4) \ + CASE0(X, ov::element::Type_t::u8) \ + CASE0(X, ov::element::Type_t::u16) \ + CASE0(X, ov::element::Type_t::u32) \ + CASE0(X, ov::element::Type_t::u64) \ + default: OPENVINO_UNREACHABLE("Unsupported element type: ", \ + "expected ", expected.get_element_type(), \ + ", actual ", actual.get_element_type()); \ + } break; + + switch (expected.get_element_type()) { + CASE(ov::element::Type_t::boolean) + CASE(ov::element::Type_t::bf16) + CASE(ov::element::Type_t::f16) + CASE(ov::element::Type_t::f32) + CASE(ov::element::Type_t::f64) + CASE(ov::element::Type_t::i4) + CASE(ov::element::Type_t::i8) + CASE(ov::element::Type_t::i16) + CASE(ov::element::Type_t::i32) + CASE(ov::element::Type_t::i64) + CASE(ov::element::Type_t::u1) + CASE(ov::element::Type_t::u4) + CASE(ov::element::Type_t::u8) + CASE(ov::element::Type_t::u16) + CASE(ov::element::Type_t::u32) + CASE(ov::element::Type_t::u64) + default: OPENVINO_UNREACHABLE("Unsupported element type: ", expected.get_element_type()); + } +#undef CASE0 +#undef CASE +} +} // namespace utils +} // namespace test +} // namespace ov \ No newline at end of file diff --git a/inference-engine/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/utils/ngraph_helpers.hpp b/inference-engine/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/utils/ngraph_helpers.hpp index aace9a22cf4..6926c3c33bc 100644 --- a/inference-engine/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/utils/ngraph_helpers.hpp +++ b/inference-engine/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/utils/ngraph_helpers.hpp @@ -269,6 +269,10 @@ std::vector>> const std::vector> &inputs, const std::vector &inputTypes = {}); +std::vector +interpreterFunction(const std::shared_ptr &function, + const std::map& inputs); + // // This function compares two nGraph functions and requires them to have exactly one output // Check nodes types diff --git a/inference-engine/tests/ngraph_helpers/ngraph_functions/src/utils/ngraph_helpers.cpp b/inference-engine/tests/ngraph_helpers/ngraph_functions/src/utils/ngraph_helpers.cpp index 18af1da8868..2489205fa24 100644 --- a/inference-engine/tests/ngraph_helpers/ngraph_functions/src/utils/ngraph_helpers.cpp +++ b/inference-engine/tests/ngraph_helpers/ngraph_functions/src/utils/ngraph_helpers.cpp @@ -144,6 +144,111 @@ std::vector>> return outputs; } +//std::vector>> +std::vector + interpreterFunction(const std::shared_ptr &function, + const std::map& inputs) { +// const std::vector> &inputs, +// const std::vector &inputTypes) { + runtime::Backend::set_backend_shared_library_search_directory(""); + auto backend = runtime::Backend::create("INTERPRETER"); + + const auto ¶meters = function->get_parameters(); + const auto ¶metersNumber = parameters.size(); + const auto &inputsNumber = inputs.size(); + NGRAPH_CHECK(parametersNumber == inputsNumber, + "Got function (", function->get_friendly_name(), ") with ", parametersNumber, " parameters, but ", + inputsNumber, " input blobs"); +// if (!inputTypes.empty()) { +// NGRAPH_CHECK(inputTypes.size() == inputsNumber, +// "Got function (", function->get_friendly_name(), ") with ", inputsNumber, " inputs, but ", +// inputTypes.size(), " types"); +// } + +// auto inputTensors = std::vector>{}; +// for (size_t i = 0; i < parametersNumber; ++i) { +// const auto ¶meter = parameters[i]; +// const auto ¶meterIndex = function->get_parameter_index(parameter); +// const auto ¶meterShape = parameter->get_shape(); +// const auto ¶meterType = parameter->get_element_type(); +// const auto ¶meterSize = shape_size(parameterShape) * parameterType.size(); +// +// auto input = inputs[parameterIndex]; +// const auto inType = inputTypes.empty() ? element::undefined : inputTypes[i]; +// +// if (inType != element::undefined && inType != parameterType) { +// input = convertOutputPrecision(input, inType, parameterType, shape_size(parameterShape)); +// } +// +// const auto &inputSize = input.size(); +// NGRAPH_CHECK(parameterSize == inputSize, +// "Got parameter (", parameter->get_friendly_name(), ") of size ", parameterSize, +// " bytes, but corresponding input with index ", parameterIndex, +// " has ", inputSize, " bytes"); +// +// auto tensor = backend->create_tensor(parameterType, parameterShape); +// tensor->write(input.data(), parameterSize); +// inputTensors.push_back(tensor); +// } + + auto inputTensors = std::vector>{}; + for (size_t i = 0; i < parametersNumber; ++i) { + const auto ¶meter = parameters[i]; +// const auto ¶meterIndex = function->get_parameter_index(parameter); + const auto ¶meterShape = parameter->get_shape(); + const auto ¶meterType = parameter->get_element_type(); + const auto ¶meterSize = shape_size(parameterShape) * parameterType.size(); + + auto inputIt = inputs.find(parameter->get_friendly_name()); + if (inputIt == inputs.end()) { + // runtime error + } + auto input = inputIt->second; +// const auto inType = inputTypes.empty() ? element::undefined : inputTypes[i]; + const auto inType = input.get_element_type(); + +// TODO: iefode +// if (inType != element::undefined && inType != parameterType) { +// input = convertOutputPrecision(input, inType, parameterType, shape_size(parameterShape)); +// } + +// const auto &inputSize = input.size(); +// NGRAPH_CHECK(parameterSize == inputSize, +// "Got parameter (", parameter->get_friendly_name(), ") of size ", parameterSize, +// " bytes, but corresponding input with index ", parameterIndex, +// " has ", inputSize, " bytes"); + + auto tensor = backend->create_tensor(parameterType, parameterShape); + tensor->write(input.data(), parameterSize); + inputTensors.push_back(tensor); + } + + auto outputTensors = std::vector>{}; + const auto &results = function->get_results(); + for (size_t i = 0; i < results.size(); ++i) { + outputTensors.push_back(std::make_shared()); + } + + auto handle = backend->compile(function); + handle->call_with_validate(outputTensors, inputTensors); +// std::vector>> outputs(results.size()); + std::vector outputs(results.size()); +// for (size_t resultIndex = 0; resultIndex < results.size(); resultIndex++) { +// auto& output = outputs[resultIndex]; +// output.first = results[resultIndex]->get_element_type(); +// const auto& outputTensor = outputTensors[resultIndex]; +// output.second.resize(ceil(shape_size(outputTensor->get_shape()) * outputTensor->get_element_type().bitwidth() / 8.f)); +// outputTensors[resultIndex]->read(output.second.data(), output.second.size()); +// } + for (const auto& outTensor : outputTensors) { + ov::runtime::Tensor a; + outTensor->read(&a, outTensor->get_size_in_bytes()); + outputs.push_back(a); + } + + return outputs; +} + std::shared_ptr foldFunction(const std::shared_ptr &function, const std::vector> &inputs, const std::vector &inputTypes) {