Skip to content

Commit 70f9084

Browse files
committed
Initial Windows support for OpenVINO backend
1 parent 462a4af commit 70f9084

4 files changed

Lines changed: 58 additions & 9 deletions

File tree

backends/openvino/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ include(${EXECUTORCH_ROOT}/tools/cmake/Utils.cmake)
3535
add_library(openvino_backend STATIC)
3636

3737
# Enable exceptions and RTTI for OpenVINO backend
38-
target_compile_options(openvino_backend PRIVATE -frtti -fexceptions)
38+
target_compile_options(
39+
openvino_backend PRIVATE
40+
$<$<CXX_COMPILER_ID:MSVC>:/GR /EHsc>
41+
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-frtti -fexceptions>
42+
)
3943

4044
# Add source files for OpenVINO backend
4145
target_sources(

backends/openvino/runtime/OpenvinoApi.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88

99
#pragma once
1010

11+
#ifdef _WIN32
12+
#include <windows.h>
13+
#else
1114
#include <dlfcn.h>
15+
#endif
1216
#include <cstddef>
1317
#include <cstdint>
1418
#include <memory>
@@ -99,7 +103,11 @@ using ov_shape_free_fn = ov_status_e (*)(ov_shape_t*);
99103
struct DlCloser {
100104
void operator()(void* handle) {
101105
if (handle) {
106+
#ifdef _WIN32
107+
FreeLibrary(static_cast<HMODULE>(handle));
108+
#else
102109
dlclose(handle);
110+
#endif
103111
}
104112
}
105113
};

backends/openvino/runtime/OpenvinoBackend.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,34 @@ namespace openvino {
2323

2424
namespace {
2525

26+
#ifdef _WIN32
27+
constexpr const char* kDefaultLibName = "openvino_c.dll";
28+
#else
2629
constexpr const char* kDefaultLibName = "libopenvino_c.so";
30+
#endif
2731

2832
template <typename FuncPtr>
2933
FuncPtr load_symbol(void* handle, const char* name) {
34+
#ifdef _WIN32
35+
void* sym =
36+
reinterpret_cast<void*>(GetProcAddress(static_cast<HMODULE>(handle), name));
37+
if (!sym) {
38+
ET_LOG(
39+
Error,
40+
"OpenVINO: failed to resolve symbol '%s': error %lu",
41+
name,
42+
GetLastError());
43+
return nullptr;
44+
}
45+
#else
3046
dlerror(); // Clear any stale error state.
3147
void* sym = dlsym(handle, name);
3248
const char* err = dlerror();
3349
if (err) {
3450
ET_LOG(Error, "OpenVINO: failed to resolve symbol '%s': %s", name, err);
3551
return nullptr;
3652
}
53+
#endif
3754
return reinterpret_cast<FuncPtr>(sym);
3855
}
3956

@@ -47,6 +64,19 @@ bool OpenvinoBackend::ensure_loaded() const {
4764
const char* lib_path = std::getenv("OPENVINO_LIB_PATH");
4865
const char* effective_path = lib_path ? lib_path : kDefaultLibName;
4966

67+
#ifdef _WIN32
68+
void* handle = static_cast<void*>(LoadLibrary(effective_path));
69+
if (!handle) {
70+
ET_LOG(
71+
Error,
72+
"OpenVINO runtime not found (LoadLibrary failed: error %lu). "
73+
"Ensure 'openvino_c.dll' is on your PATH "
74+
"(set OPENVINO_LIB_PATH), or install with: "
75+
"pip install \"openvino>=2025.1.0,<2026.0.0\"",
76+
GetLastError());
77+
return;
78+
}
79+
#else
5080
void* handle = dlopen(effective_path, RTLD_NOW | RTLD_LOCAL);
5181
if (!handle) {
5282
ET_LOG(
@@ -58,6 +88,7 @@ bool OpenvinoBackend::ensure_loaded() const {
5888
dlerror());
5989
return;
6090
}
91+
#endif
6192
lib_handle_.reset(handle);
6293

6394
#define LOAD_SYM(field, symbol_name) \

extension/pybindings/portable_lib.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
logger = logging.getLogger(__name__)
3535

3636
# Auto-discover the OpenVINO C library path from the pip-installed openvino
37-
# package so the C++ backend's dlopen("libopenvino_c.so") works without the
38-
# user having to set LD_LIBRARY_PATH or OPENVINO_LIB_PATH manually.
37+
# package so the C++ backend's dlopen/LoadLibrary call works without the user
38+
# having to set LD_LIBRARY_PATH or OPENVINO_LIB_PATH manually.
3939
if not os.environ.get("OPENVINO_LIB_PATH"):
4040
try:
4141
import glob
@@ -44,18 +44,24 @@
4444
spec = importlib.util.find_spec("openvino")
4545
if spec is not None and spec.submodule_search_locations:
4646
_ov_dir = spec.submodule_search_locations[0]
47-
_ov_libs = sorted(
48-
glob.glob(os.path.join(_ov_dir, "libs", "libopenvino_c.so*"))
49-
)
47+
_ov_libs_dir = os.path.join(_ov_dir, "libs")
48+
if sys.platform == "win32":
49+
_lib_pattern = os.path.join(_ov_libs_dir, "openvino_c.dll")
50+
else:
51+
_lib_pattern = os.path.join(_ov_libs_dir, "libopenvino_c.so*")
52+
_ov_libs = sorted(glob.glob(_lib_pattern))
5053
if _ov_libs:
5154
os.environ["OPENVINO_LIB_PATH"] = _ov_libs[0]
55+
if sys.platform == "win32":
56+
os.add_dll_directory(_ov_libs_dir)
5257
else:
5358
logger.warning(
54-
"OpenVINO package found but libopenvino_c.so not in %s; "
59+
"OpenVINO package found but %s not in %s; "
5560
"set OPENVINO_LIB_PATH manually if needed",
56-
os.path.join(_ov_dir, "libs"),
61+
"openvino_c.dll" if sys.platform == "win32" else "libopenvino_c.so",
62+
_ov_libs_dir,
5763
)
58-
del _ov_libs, _ov_dir, spec
64+
del _ov_libs, _ov_libs_dir, _lib_pattern, _ov_dir, spec
5965
except Exception as e:
6066
logger.debug("OpenVINO auto-discovery failed: %s", e)
6167

0 commit comments

Comments
 (0)