Skip to content

Commit 2723b8c

Browse files
committed
feat: Add OpenVINO binding for semantic routing
Signed-off-by: Huamin Chen <[email protected]>
1 parent a149800 commit 2723b8c

34 files changed

+5884
-0
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ _run:
88
-f tools/make/envoy.mk \
99
-f tools/make/golang.mk \
1010
-f tools/make/rust.mk \
11+
-f tools/make/openvino.mk \
1112
-f tools/make/build-run-test.mk \
1213
-f tools/make/docs.mk \
1314
-f tools/make/linter.mk \

openvino-binding/.gitignore

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Build artifacts
2+
build/
3+
*.so
4+
*.dylib
5+
*.dll
6+
*.a
7+
*.lib
8+
9+
# CMake
10+
CMakeCache.txt
11+
CMakeFiles/
12+
cmake_install.cmake
13+
Makefile
14+
compile_commands.json
15+
16+
# Go
17+
*.test
18+
*.out
19+
*.exe
20+
21+
# IDE
22+
.vscode/
23+
.idea/
24+
*.swp
25+
*.swo
26+
*~
27+
28+
# OS
29+
.DS_Store
30+
Thumbs.db
31+
32+
# Temporary files
33+
*.log
34+
*.tmp
35+
*.temp
36+
37+
# Models (too large for git)
38+
models/
39+
*.xml
40+
*.bin
41+
*.onnx
42+
*.pt
43+
*.pth
44+
*.safetensors
45+
46+
# Test outputs
47+
test_output/
48+
results/

openvino-binding/CMakeLists.txt

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
cmake_minimum_required(VERSION 3.13)
2+
project(openvino_semantic_router VERSION 0.1.0 LANGUAGES CXX)
3+
4+
set(CMAKE_CXX_STANDARD 17)
5+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
6+
set(CMAKE_CXX_EXTENSIONS OFF)
7+
8+
# Suppress undefined variable warnings in generated Makefiles
9+
set(CMAKE_COLOR_MAKEFILE ON)
10+
set(CMAKE_VERBOSE_MAKEFILE OFF)
11+
12+
# Find OpenVINO - try multiple approaches
13+
find_package(OpenVINO QUIET COMPONENTS Runtime)
14+
15+
if(NOT OpenVINO_FOUND)
16+
message(STATUS "OpenVINO not found via find_package, trying Python site-packages...")
17+
18+
# Try to find OpenVINO in Python site-packages
19+
find_package(Python3 COMPONENTS Interpreter)
20+
if(Python3_FOUND)
21+
execute_process(
22+
COMMAND "${Python3_EXECUTABLE}" -c "import openvino; print(openvino.__path__[0])"
23+
OUTPUT_VARIABLE OPENVINO_PYTHON_PATH
24+
OUTPUT_STRIP_TRAILING_WHITESPACE
25+
RESULT_VARIABLE PYTHON_IMPORT_RESULT
26+
)
27+
28+
if(PYTHON_IMPORT_RESULT EQUAL 0 AND EXISTS "${OPENVINO_PYTHON_PATH}")
29+
message(STATUS "Found OpenVINO Python installation at: ${OPENVINO_PYTHON_PATH}")
30+
31+
# Set paths for CMake
32+
set(OpenVINO_DIR "${OPENVINO_PYTHON_PATH}/cmake")
33+
set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${OPENVINO_PYTHON_PATH}/cmake")
34+
35+
# Try to find OpenVINO again with the Python path
36+
find_package(OpenVINO QUIET COMPONENTS Runtime PATHS "${OPENVINO_PYTHON_PATH}/cmake" NO_DEFAULT_PATH)
37+
38+
if(OpenVINO_FOUND)
39+
message(STATUS "Successfully configured OpenVINO from Python site-packages")
40+
else()
41+
# Manual configuration fallback
42+
message(STATUS "Manual OpenVINO configuration from Python site-packages")
43+
set(OpenVINO_FOUND TRUE)
44+
set(OPENVINO_INCLUDE_DIRS "${OPENVINO_PYTHON_PATH}/runtime/include")
45+
set(OPENVINO_LIBRARY_DIRS "${OPENVINO_PYTHON_PATH}/libs")
46+
47+
# Create imported target manually
48+
add_library(openvino::runtime SHARED IMPORTED)
49+
set_target_properties(openvino::runtime PROPERTIES
50+
IMPORTED_LOCATION "${OPENVINO_LIBRARY_DIRS}/libopenvino.so"
51+
INTERFACE_INCLUDE_DIRECTORIES "${OPENVINO_INCLUDE_DIRS}"
52+
)
53+
endif()
54+
endif()
55+
endif()
56+
endif()
57+
58+
if(NOT OpenVINO_FOUND)
59+
message(FATAL_ERROR "OpenVINO not found. Please install OpenVINO or set OpenVINO_DIR environment variable.")
60+
endif()
61+
62+
message(STATUS "OpenVINO found and configured successfully")
63+
64+
# Find OpenVINO Tokenizers library
65+
set(OPENVINO_TOKENIZERS_LIB_DIR "")
66+
if(Python3_FOUND AND OPENVINO_PYTHON_PATH)
67+
# Check if openvino_tokenizers exists in same Python installation
68+
execute_process(
69+
COMMAND "${Python3_EXECUTABLE}" -c "import openvino_tokenizers; print(openvino_tokenizers.__path__[0])"
70+
OUTPUT_VARIABLE OPENVINO_TOKENIZERS_PATH
71+
OUTPUT_STRIP_TRAILING_WHITESPACE
72+
RESULT_VARIABLE TOKENIZERS_IMPORT_RESULT
73+
)
74+
75+
if(TOKENIZERS_IMPORT_RESULT EQUAL 0 AND EXISTS "${OPENVINO_TOKENIZERS_PATH}")
76+
set(OPENVINO_TOKENIZERS_LIB_DIR "${OPENVINO_TOKENIZERS_PATH}/lib")
77+
message(STATUS "Found OpenVINO Tokenizers: ${OPENVINO_TOKENIZERS_LIB_DIR}")
78+
79+
# Verify library files exist
80+
if(EXISTS "${OPENVINO_TOKENIZERS_LIB_DIR}/libopenvino_tokenizers.so")
81+
message(STATUS " ✓ libopenvino_tokenizers.so found")
82+
endif()
83+
if(EXISTS "${OPENVINO_TOKENIZERS_LIB_DIR}/libcore_tokenizers.so")
84+
message(STATUS " ✓ libcore_tokenizers.so found")
85+
endif()
86+
endif()
87+
endif()
88+
89+
if(NOT OPENVINO_TOKENIZERS_LIB_DIR OR NOT EXISTS "${OPENVINO_TOKENIZERS_LIB_DIR}")
90+
message(WARNING "OpenVINO Tokenizers library not found. Install with: pip install openvino-tokenizers")
91+
endif()
92+
93+
# Library sources (modular architecture)
94+
set(SOURCES
95+
# Utils module
96+
cpp/src/utils/math_utils.cpp
97+
cpp/src/utils/preprocessing.cpp
98+
99+
# Core module
100+
cpp/src/core/model_manager.cpp
101+
cpp/src/core/tokenizer.cpp
102+
103+
# Classifiers module
104+
cpp/src/classifiers/text_classifier.cpp
105+
cpp/src/classifiers/token_classifier.cpp
106+
107+
# Embeddings module
108+
cpp/src/embeddings/embedding_generator.cpp
109+
110+
# FFI layer (C API for Go CGO)
111+
cpp/src/ffi/openvino_semantic_router_ffi.cpp
112+
)
113+
114+
set(HEADERS
115+
# C API header (public interface)
116+
cpp/include/openvino_semantic_router.h
117+
118+
# Core headers
119+
cpp/include/core/types.h
120+
cpp/include/core/model_manager.h
121+
cpp/include/core/tokenizer.h
122+
123+
# Classifier headers
124+
cpp/include/classifiers/text_classifier.h
125+
cpp/include/classifiers/token_classifier.h
126+
127+
# Embedding headers
128+
cpp/include/embeddings/embedding_generator.h
129+
130+
# Utility headers
131+
cpp/include/utils/math_utils.h
132+
cpp/include/utils/preprocessing.h
133+
)
134+
135+
# Create shared library
136+
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS})
137+
138+
# Include directories
139+
target_include_directories(${PROJECT_NAME}
140+
PUBLIC
141+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/cpp/include>
142+
$<INSTALL_INTERFACE:include>
143+
PRIVATE
144+
${CMAKE_CURRENT_SOURCE_DIR}/cpp/src
145+
)
146+
147+
# Link OpenVINO and OpenVINO Tokenizers
148+
target_link_libraries(${PROJECT_NAME}
149+
PUBLIC
150+
openvino::runtime
151+
)
152+
153+
# Link OpenVINO Tokenizers if available
154+
if(OPENVINO_TOKENIZERS_LIB_DIR AND EXISTS "${OPENVINO_TOKENIZERS_LIB_DIR}/libopenvino_tokenizers.so")
155+
target_link_libraries(${PROJECT_NAME}
156+
PRIVATE
157+
${OPENVINO_TOKENIZERS_LIB_DIR}/libopenvino_tokenizers.so
158+
)
159+
160+
# Add rpath so the library can be found at runtime
161+
set_target_properties(${PROJECT_NAME} PROPERTIES
162+
BUILD_RPATH "${OPENVINO_TOKENIZERS_LIB_DIR}"
163+
INSTALL_RPATH "${OPENVINO_TOKENIZERS_LIB_DIR}"
164+
)
165+
166+
message(STATUS "Linked OpenVINO Tokenizers library")
167+
endif()
168+
169+
# Compiler options
170+
target_compile_options(${PROJECT_NAME} PRIVATE
171+
$<$<CXX_COMPILER_ID:GNU,Clang,AppleClang>:-Wall -Wextra -Wpedantic>
172+
$<$<CXX_COMPILER_ID:MSVC>:/W4>
173+
)
174+
175+
# Set library output properties
176+
set_target_properties(${PROJECT_NAME} PROPERTIES
177+
VERSION ${PROJECT_VERSION}
178+
SOVERSION 0
179+
PUBLIC_HEADER "${HEADERS}"
180+
)
181+
182+
# Installation rules
183+
include(GNUInstallDirs)
184+
185+
install(TARGETS ${PROJECT_NAME}
186+
EXPORT ${PROJECT_NAME}Targets
187+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
188+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
189+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
190+
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
191+
)
192+
193+
install(EXPORT ${PROJECT_NAME}Targets
194+
FILE ${PROJECT_NAME}Targets.cmake
195+
NAMESPACE ${PROJECT_NAME}::
196+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
197+
)
198+
199+
# Create package configuration files
200+
include(CMakePackageConfigHelpers)
201+
202+
configure_package_config_file(
203+
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in"
204+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
205+
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
206+
)
207+
208+
write_basic_package_version_file(
209+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
210+
VERSION ${PROJECT_VERSION}
211+
COMPATIBILITY AnyNewerVersion
212+
)
213+
214+
install(FILES
215+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
216+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
217+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
218+
)
219+
220+
# Print configuration summary
221+
message(STATUS "========================================")
222+
message(STATUS "OpenVINO Semantic Router Configuration")
223+
message(STATUS "========================================")
224+
message(STATUS "Version: ${PROJECT_VERSION}")
225+
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
226+
message(STATUS "C++ standard: ${CMAKE_CXX_STANDARD}")
227+
message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}")
228+
message(STATUS "========================================")
229+

openvino-binding/README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# OpenVINO Binding for Semantic Router
2+
3+
High-performance Go bindings for semantic routing using Intel® OpenVINO™ Toolkit. This binding provides BERT-based text embeddings, similarity search, and classification capabilities optimized for Intel CPUs and accelerators.
4+
5+
## Features
6+
7+
- 🚀 **High Performance**: Optimized inference with OpenVINO on Intel hardware
8+
- 🔍 **Semantic Search**: BERT embeddings and cosine similarity
9+
- 📊 **Classification**: Text classification with confidence scores
10+
- 🏷️ **Token Classification**: Named entity recognition and PII detection
11+
- 🔄 **Batch Processing**: Efficient batch similarity computation
12+
- 💻 **Multi-Device**: Support for CPU, GPU, VPU, and other Intel accelerators
13+
- 🔌 **CGO Bindings**: Native C++ integration with Go
14+
15+
## Environment Variables
16+
17+
The following environment variables are required or recommended:
18+
19+
- **`OPENVINO_TOKENIZERS_LIB`** (Required): Path to `libopenvino_tokenizers.so`
20+
21+
```bash
22+
export OPENVINO_TOKENIZERS_LIB="/path/to/libopenvino_tokenizers.so"
23+
```
24+
25+
- **`OPENVINO_MODEL_PATH`** (Optional): Path to OpenVINO model XML file
26+
- Default: `../../test_models/category_classifier_modernbert/openvino_model.xml`
27+
28+
- **`CANDLE_MODEL_PATH`** (Optional): Path to Candle model directory (for benchmarks)
29+
- Default: `../../../models/category_classifier_modernbert-base_model`
30+
31+
- **`LD_LIBRARY_PATH`** (Required): Include the path to the built library
32+
33+
```bash
34+
export LD_LIBRARY_PATH="/path/to/openvino-binding/build:$LD_LIBRARY_PATH"
35+
```
36+
37+
## Building
38+
39+
### 1. Build C++ Library
40+
41+
```bash
42+
cd openvino-binding
43+
44+
# Create build directory
45+
mkdir -p build
46+
cd build
47+
48+
# Configure with CMake
49+
cmake .. -DCMAKE_BUILD_TYPE=Release
50+
51+
# Build
52+
cmake --build . -j$(nproc)
53+
54+
# Install (optional)
55+
sudo cmake --install .
56+
```
57+
58+
### 2. Build Go Bindings
59+
60+
```bash
61+
# Go back to openvino-binding directory
62+
cd ..
63+
64+
# Test Go bindings
65+
go build -v ./...
66+
67+
# Run tests (if available)
68+
go test -v ./...
69+
```
70+
71+
## Running Benchmarks
72+
73+
The benchmark compares OpenVINO and Candle implementations:
74+
75+
```bash
76+
# Set up environment variables
77+
export OPENVINO_TOKENIZERS_LIB="/path/to/libopenvino_tokenizers.so"
78+
export OPENVINO_MODEL_PATH="/path/to/openvino_model.xml"
79+
export CANDLE_MODEL_PATH="/path/to/candle/model"
80+
export LD_LIBRARY_PATH="/path/to/openvino-binding/build:/path/to/candle-binding/target/release:$LD_LIBRARY_PATH"
81+
82+
# Run benchmark
83+
cd cmd/benchmark
84+
go run main.go
85+
```
86+
87+
## Converting Models to OpenVINO IR Format
88+
89+
OpenVINO requires models in Intermediate Representation (IR) format (`.xml` and `.bin` files).
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@PACKAGE_INIT@
2+
3+
include(CMakeFindDependencyMacro)
4+
5+
find_dependency(OpenVINO REQUIRED COMPONENTS Runtime)
6+
7+
include("${CMAKE_CURRENT_LIST_DIR}/openvino_semantic_routerTargets.cmake")
8+
9+
check_required_components(openvino_semantic_router)
10+

0 commit comments

Comments
 (0)