Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/inference/dev_api/openvino/runtime/icore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ class OPENVINO_RUNTIME_API ICore {
* @param properties Optional map of pairs: (property name, property value) relevant only for this read operation.
* @return shared pointer to ov::Model
*/
virtual std::shared_ptr<ov::Model> read_model(const std::string& model_path,
const std::string& bin_path,
const AnyMap& properties) const = 0;
virtual std::shared_ptr<ov::Model> read_model(const std::filesystem::path& model_path,
const std::filesystem::path& bin_path,
const ov::AnyMap& properties) const = 0;

virtual ov::AnyMap create_compile_config(const std::string& device_name, const ov::AnyMap& origConfig) const = 0;

Expand Down
22 changes: 11 additions & 11 deletions src/inference/include/openvino/runtime/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,18 @@ class OPENVINO_RUNTIME_API Core {
const std::string& bin_path = {},
const ov::AnyMap& properties = {}) const;

template <class Path, std::enable_if_t<std::is_same_v<Path, std::filesystem::path>>* = nullptr>
std::shared_ptr<ov::Model> read_model(const std::filesystem::path& model_path,
const std::filesystem::path& bin_path = {},
const ov::AnyMap& properties = {}) const;

template <class Path>
auto read_model(const Path& model_path, const Path& bin_path = {}, const ov::AnyMap& properties = {}) const {
if constexpr (std::is_same_v<typename Path::value_type, wchar_t>) {
return read_model(model_path.wstring(), bin_path.wstring(), properties);
if constexpr (std::is_constructible_v<std::string, Path>) {
return read_model(std::string(model_path), std::string(bin_path), properties);
} else if constexpr (std::is_constructible_v<std::wstring, Path>) {
return read_model(std::wstring(model_path), std::wstring(bin_path), properties);
} else {
// use string conversion as default
return read_model(model_path.string(), bin_path.string(), properties);
return read_model(std::filesystem::path(model_path), std::filesystem::path(bin_path), properties);
}
}
/// @}
Expand Down Expand Up @@ -151,12 +156,7 @@ class OPENVINO_RUNTIME_API Core {
class... Properties,
std::enable_if_t<std::is_same_v<Path, std::filesystem::path> && (sizeof...(Properties) > 0)>* = nullptr>
auto read_model(const Path& model_path, const Path& bin_path, Properties&&... properties) const {
if constexpr (std::is_same_v<typename Path::value_type, wchar_t>) {
return read_model(model_path.wstring(), bin_path.wstring(), std::forward<Properties>(properties)...);
} else {
// use string conversion as default
return read_model(model_path.string(), bin_path.string(), std::forward<Properties>(properties)...);
}
return read_model(model_path, bin_path, AnyMap{std::forward<Properties>(properties)...});
}
/// @}

Expand Down
17 changes: 12 additions & 5 deletions src/inference/src/cpp/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,23 +74,30 @@ Core::Core(const std::filesystem::path& xml_config_file) : _impl(std::make_share
}

std::map<std::string, Version> Core::get_versions(const std::string& device_name) const {
OV_CORE_CALL_STATEMENT({ return _impl->get_versions(device_name); })}
OV_CORE_CALL_STATEMENT(return _impl->get_versions(device_name););
}

std::shared_ptr<ov::Model> Core::read_model(const std::filesystem::path& model_path,
const std::filesystem::path& bin_path,
const ov::AnyMap& properties) const {
OV_ITT_SCOPED_REGION_BASE(ov::itt::domains::OV, "Read model");
OV_CORE_CALL_STATEMENT(return _impl->read_model(model_path, bin_path, properties););
}

#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
std::shared_ptr<ov::Model> Core::read_model(const std::wstring& model_path,
const std::wstring& bin_path,
const ov::AnyMap& properties) const {
OV_ITT_SCOPED_REGION_BASE(ov::itt::domains::OV, "Read model");
OV_CORE_CALL_STATEMENT(return _impl->read_model(ov::util::wstring_to_string(model_path),
ov::util::wstring_to_string(bin_path),
properties););
return read_model(ov::util::make_path(model_path), ov::util::make_path(bin_path), properties);
}
#endif

std::shared_ptr<ov::Model> Core::read_model(const std::string& model_path,
const std::string& bin_path,
const AnyMap& properties) const {
OV_ITT_SCOPED_REGION_BASE(ov::itt::domains::OV, "Read model");
OV_CORE_CALL_STATEMENT(return _impl->read_model(model_path, bin_path, properties););
return read_model(ov::util::make_path(model_path), ov::util::make_path(bin_path), properties);
}

std::shared_ptr<ov::Model> Core::read_model(const std::string& model, const ov::Tensor& weights) const {
Expand Down
9 changes: 3 additions & 6 deletions src/inference/src/dev/core_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1726,16 +1726,13 @@ void ov::CoreImpl::add_mutex(const std::string& dev_name) {
m_dev_mutexes[dev_name];
}

std::shared_ptr<ov::Model> ov::CoreImpl::read_model(const std::string& modelPath,
const std::string& binPath,
std::shared_ptr<ov::Model> ov::CoreImpl::read_model(const std::filesystem::path& model_path,
const std::filesystem::path& bin_path,
const AnyMap& properties) const {
OV_ITT_SCOPE(FIRST_INFERENCE, ov::itt::domains::ReadTime, "CoreImpl::read_model from file");
auto local_core_config = m_core_config;
local_core_config.set(properties, {});
return ov::util::read_model(ov::util::make_path(modelPath),
ov::util::make_path(binPath),
get_extensions_copy(),
local_core_config.get_enable_mmap());
return ov::util::read_model(model_path, bin_path, get_extensions_copy(), local_core_config.get_enable_mmap());
}

std::shared_ptr<ov::Model> ov::CoreImpl::read_model(const std::string& model,
Expand Down
6 changes: 3 additions & 3 deletions src/inference/src/dev/core_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,9 @@ class CoreImpl : public ov::ICore, public std::enable_shared_from_this<ov::ICore
std::shared_ptr<ov::Model> read_model(const std::shared_ptr<AlignedBuffer>& model,
const std::shared_ptr<AlignedBuffer>& weights) const override;

std::shared_ptr<ov::Model> read_model(const std::string& model_path,
const std::string& bin_path,
const AnyMap& properties) const override;
std::shared_ptr<ov::Model> read_model(const std::filesystem::path& model_path,
const std::filesystem::path& bin_path,
const ov::AnyMap& properties) const override;

ov::SoPtr<ov::ICompiledModel> compile_model(const std::shared_ptr<const ov::Model>& model,
const std::string& device_name,
Expand Down
2 changes: 1 addition & 1 deletion src/inference/src/dev/iplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ std::shared_ptr<ov::ICompiledModel> ov::IPlugin::compile_model(const std::string
const ov::AnyMap& properties) const {
auto core = get_core();
OPENVINO_ASSERT(core);
const auto model = core->read_model(model_path, {}, properties);
const auto model = core->read_model(util::make_path(model_path), {}, properties);
auto local_properties = properties;
if (!ov::is_virtual_device(get_device_name())) {
CoreConfig::remove_core(local_properties);
Expand Down
3 changes: 1 addition & 2 deletions src/inference/src/model_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,7 @@ std::shared_ptr<ov::Model> read_model(const std::filesystem::path& model_path,
model_path,
" Please check that model format: ",
model_path.extension(),
" is supported and the model is correct.",
" Available frontends: ",
" is supported and the model is correct. Available frontends: ",
FEs);
}

Expand Down
24 changes: 13 additions & 11 deletions src/inference/tests/functional/ov_core_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,27 +240,29 @@ TEST_F(CoreBaseTest, compile_model_with_std_fs_path) {
#endif
}

TEST_P(UnicodePathTest, core_compile_model) {
TEST_P(UnicodePathTest, read_compile_model) {
const std::string model_name = "test-model";
const auto prefix_dir = utils::generateTestFilePrefix();
const auto test_dir = std::filesystem::path(prefix_dir) / fs_path_from_variant();
const auto test_dir = std::filesystem::path(prefix_dir) / utils::to_fs_path(GetParam());

const auto model_path = test_dir / std::filesystem::path(model_name + ".xml");
const auto weight_path = test_dir / std::filesystem::path(model_name + ".bin");
ov::test::utils::generate_test_model(model_path, weight_path);

ov::Core core;
{
const auto model = core.compile_model(model_path);
EXPECT_TRUE(model);
}
{
const auto devices = core.get_available_devices();
const auto visitor = [&](const auto& param) {
using ParamT = std::decay_t<decltype(param)>;
auto folder = ov::test::utils::ensure_trailing_slash(ParamT(param));
Copy link
Contributor Author

@almilosz almilosz Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it crucial for UnicodePathTest, create_directories to test both "test_encoder/test_encoder.encrypted/", and "test_encoder/test_encoder.encrypted"? If yes, I think it's better to modify create_directories test, if no, test one of these options

TEST_P(UnicodePathTest, create_directories) {

auto model_path = utils::cast_string_to_type<ParamT>(prefix_dir + "/") + folder +
utils::cast_string_to_type<ParamT>(model_name + ".xml");

const auto model = core.compile_model(model_path, devices.at(0), ov::AnyMap{});
EXPECT_TRUE(model);
}
const auto model = core.read_model(model_path);
EXPECT_NE(model, nullptr);

const auto compiled_model = core.compile_model(model_path);
EXPECT_TRUE(compiled_model);
};
run_test_visitor(visitor);
std::filesystem::remove_all(prefix_dir);
}

Expand Down
4 changes: 3 additions & 1 deletion src/plugins/intel_npu/src/plugin/src/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "npuw/llm_compiled_model.hpp"
#include "npuw/serialization.hpp"
#include "openvino/core/rt_info/weightless_caching_attributes.hpp"
#include "openvino/util/file_util.hpp"
#include "openvino/op/constant.hpp"
#include "openvino/op/parameter.hpp"
#include "openvino/runtime/intel_npu/properties.hpp"
Expand Down Expand Up @@ -1221,7 +1222,8 @@ std::shared_ptr<ov::ICompiledModel> Plugin::parse(const ov::Tensor& tensorBig,
". A \".bin\" or \".onnx\" extension was expected.");
}

originalModel = get_core()->read_model(xmlPath, weightsPath, properties);
originalModel =
get_core()->read_model(ov::util::make_path(xmlPath), ov::util::make_path(weightsPath), properties);
} else {
OPENVINO_THROW("Attempted to load a weightless compiled model, but no weights have been provided");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
#include "gtest/gtest.h"
#include "openvino/util/file_util.hpp"

#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT

namespace ov {
namespace test {
namespace utils {

#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT

inline void fixSlashes(std::string& str) {
std::replace(str.begin(), str.end(), '/', '\\');
}
Expand Down Expand Up @@ -160,15 +160,48 @@ inline int removeDir(std::wstring path) {

extern const std::vector<std::wstring> test_unicode_postfix_vector;

#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT

template <typename ParamT>
ParamT cast_string_to_type(const std::string& value) {
OPENVINO_THROW("Unsupported string type requested");
return ParamT{};
}

template <>
std::string cast_string_to_type<std::string>(const std::string& value);

template <>
std::wstring cast_string_to_type<std::wstring>(const std::string& value);

template <>
std::u16string cast_string_to_type<std::u16string>(const std::string& value);

template <>
std::u32string cast_string_to_type<std::u32string>(const std::string& value);

template <typename StringT>
StringT ensure_trailing_slash(StringT value) {
using CharT = typename StringT::value_type;
if (value.empty() || value.back() != static_cast<CharT>('/')) {
value.push_back(static_cast<CharT>('/'));
}
return value;
}

} // namespace utils
} // namespace test
} // namespace ov
#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT

namespace ov::test {
class UnicodePathTest : public testing::Test, public ::testing::WithParamInterface<utils::StringPathVariant> {
protected:
std::filesystem::path get_path_param() const;
std::filesystem::path fs_path_from_variant() const;

template <class TestVisitor>
auto run_test_visitor(TestVisitor&& func) {
return std::visit(func, GetParam());
}
};
} // namespace ov::test
45 changes: 37 additions & 8 deletions src/tests/test_utils/common_test_utils/src/unicode_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,24 @@

#include "common_test_utils/unicode_utils.hpp"

#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
namespace {

template <typename CharT>
std::basic_string<CharT> convert_ascii_string(const std::string& value) {
std::basic_string<CharT> converted;
converted.reserve(value.size());
for (unsigned char ch : value) {
converted.push_back(static_cast<CharT>(ch));
}
return converted;
}

} // namespace

namespace ov::test {

namespace ov {
namespace test {
namespace utils {
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT

const std::vector<std::wstring> test_unicode_postfix_vector = {L"unicode_Яㅎあ",
L"ひらがな日本語",
Expand All @@ -19,13 +32,29 @@ const std::vector<std::wstring> test_unicode_postfix_vector = {L"unicode_Яㅎ
L"АБВГДЕЁЖЗИЙ",
L"СТУФХЦЧШЩЬЮЯ"};

} // namespace utils
} // namespace test
} // namespace ov

#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT

namespace ov::test {
template <>
std::string cast_string_to_type<std::string>(const std::string& value) {
return value;
}

template <>
std::wstring cast_string_to_type<std::wstring>(const std::string& value) {
return ov::util::string_to_wstring(value);
}

template <>
std::u16string cast_string_to_type<std::u16string>(const std::string& value) {
return convert_ascii_string<char16_t>(value);
}

template <>
std::u32string cast_string_to_type<std::u32string>(const std::string& value) {
return convert_ascii_string<char32_t>(value);
}

} // namespace utils

std::filesystem::path UnicodePathTest::get_path_param() const {
return std::visit(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class MockICore : public ov::ICore {
MOCK_METHOD(std::shared_ptr<ov::Model>, read_model, (const std::string&, const ov::Tensor&, bool), (const));
MOCK_METHOD(std::shared_ptr<ov::Model>,
read_model,
(const std::string&, const std::string&, const ov::AnyMap&),
(const std::filesystem::path&, const std::filesystem::path&, const ov::AnyMap&),
(const));
MOCK_METHOD(std::shared_ptr<ov::Model>,
read_model,
Expand Down
Loading