Skip to content

CPP Python bindings accuracy tests #287

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 41 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
7c89b2a
Add tests for py bindings
sovrasov Jan 29, 2025
12c7e0d
Fix linter
sovrasov Jan 29, 2025
18d1cb9
Del outdated OMZ model
sovrasov Jan 29, 2025
75ffbf8
Disable yolo python tests
sovrasov Jan 30, 2025
7829746
Disable cpp yolo tests as well
sovrasov Jan 30, 2025
df10b25
Minor fixes in cpp samples
sovrasov Jan 30, 2025
9dd9fcb
Update cmake in tests
sovrasov Jan 30, 2025
ae532aa
Revert py OV in tests cmake
sovrasov Jan 30, 2025
ad192ab
Use python from venv only
sovrasov Jan 30, 2025
6d2de0c
Specify python dir manually
sovrasov Jan 30, 2025
0e2f3cb
Merge remote-tracking branch 'origin/master' into vs/bindings_tests
sovrasov Feb 7, 2025
16c7bbd
Enable bindings in cpp accuracy tests
sovrasov Feb 7, 2025
6cbce37
Merge remote-tracking branch 'origin/master' into vs/bindings_tests
sovrasov Feb 7, 2025
6ef53ed
Merge ModelBase into ImageModel
RHeckerIntel Apr 2, 2025
d029524
Merge branch 'master' into rhecker/refactor
RHeckerIntel Apr 3, 2025
7bc1bbe
Fix clang linter
RHeckerIntel Apr 4, 2025
a068643
Merge branch 'master' into rhecker/refactor
RHeckerIntel Apr 4, 2025
ccbfcbb
Rename ImageModel to BaseModel
RHeckerIntel Apr 7, 2025
312a2dc
Python binding compilation test area
RHeckerIntel Apr 10, 2025
fb07cb5
Working with openvino from python package.
RHeckerIntel Apr 10, 2025
0ec186d
Add Dockerfile for building the python bindings from c++
RHeckerIntel Apr 10, 2025
4decb8f
Working python wheel package with only opencv as dependency
RHeckerIntel Apr 11, 2025
fbed5dd
Clean up the Dockerfile.ubuntu for building the python package
RHeckerIntel Apr 11, 2025
bc001ff
Remove rpath setting
RHeckerIntel Apr 11, 2025
ffc65ea
Extract opencv dependencies and setup windows part too
RHeckerIntel Apr 14, 2025
3fb1326
Clean up cmakelists, sadly its been broken since last couple commits
RHeckerIntel Apr 14, 2025
0a81303
Revert "Clean up cmakelists, sadly its been broken since last couple …
RHeckerIntel Apr 14, 2025
cb0020c
Revert "Extract opencv dependencies and setup windows part too"
RHeckerIntel Apr 14, 2025
0d655cb
Fix cmake file properly now for ubuntu
RHeckerIntel Apr 14, 2025
a229e7f
Fixing windows build again
RHeckerIntel Apr 14, 2025
bd0f4a5
Merge remote-tracking branch 'vlad/vs/bindings_tests' into rhecker/py…
RHeckerIntel Apr 14, 2025
cd9bf79
Fix tests for cpp-py so that they run, not working yet
RHeckerIntel Apr 14, 2025
230547e
Merge branch 'master' into rhecker/py-bindings-tests
RHeckerIntel Apr 14, 2025
ff67f11
Try to fix workflow
RHeckerIntel Apr 14, 2025
a263dd9
Remove cpp tests and use venv for building package
RHeckerIntel Apr 14, 2025
df0a356
Remove the broken test and enable cpp tests again
RHeckerIntel Apr 14, 2025
09765a7
Clean up a bit
RHeckerIntel Apr 15, 2025
dd7383c
make sure the .so's are included.
RHeckerIntel Apr 15, 2025
35ade26
Apply feedback, remove docker files
RHeckerIntel Apr 15, 2025
831f18b
Rename the py project for py bindings to vision api
RHeckerIntel Apr 16, 2025
4f793e4
Debug why model api is not found
RHeckerIntel Apr 16, 2025
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
9 changes: 9 additions & 0 deletions .github/workflows/test_accuracy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ jobs:
pip install typing_extensions==4.12.2
cmake ../tests/cpp/accuracy/
make -j
- name: Build CPP-PY Bindings
run: |
source venv/bin/activate
pip install src/cpp/py_bindings
- name: Run CPP Test
run: |
build/test_accuracy -d data -p tests/python/accuracy/public_scope.json
- name: Run CPP-PY Bindings Test
run: |
source venv/bin/activate
pip list
pytest --data=./data --config=./tests/python/accuracy/public_scope.json tests/cpp/accuracy/test_bindings.py
1 change: 0 additions & 1 deletion examples/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ endmacro()

find_package(OpenCV REQUIRED COMPONENTS imgcodecs)

set (ENABLE_PY_BINDINGS OFF)
add_subdirectory(../../src/cpp ${Samples_BINARY_DIR}/src/cpp)

add_example(NAME asynchronous_api SOURCES ./asynchronous_api/main.cpp DEPENDENCIES model_api)
Expand Down
6 changes: 0 additions & 6 deletions src/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

cmake_minimum_required(VERSION 3.26)

option(ENABLE_PY_BINDINGS "Enables building python bindings package" ON)

# Multi config generators such as Visual Studio ignore CMAKE_BUILD_TYPE. Multi config generators are configured with
# CMAKE_CONFIGURATION_TYPES, but limiting options in it completely removes such build options
get_property(GENERATOR_IS_MULTI_CONFIG_VAR GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
Expand Down Expand Up @@ -77,10 +75,6 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "^GNU|(Apple)?Clang$")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
endif()

if (ENABLE_PY_BINDINGS)
add_subdirectory(py_bindings)
endif()

include(GenerateExportHeader)

generate_export_header(model_api)
Expand Down
3 changes: 3 additions & 0 deletions src/cpp/py_bindings/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.whl
*.dll
*.so*
30 changes: 20 additions & 10 deletions src/cpp/py_bindings/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@
# SPDX-License-Identifier: Apache-2.0
#

cmake_minimum_required(VERSION 3.26)

if(WIN32)
set(CMAKE_GENERATOR_TOOLSET "v142")
endif()


add_subdirectory(../ model_api/cpp)

set(Python_FIND_VIRTUALENV FIRST)
project(_vision_api LANGUAGES CXX)
find_package(Python COMPONENTS Interpreter Development REQUIRED)

execute_process(
Expand All @@ -11,17 +21,17 @@ execute_process(
find_package(nanobind CONFIG REQUIRED)


file(GLOB BINDINGS_SOURCES ./*.cpp)
file(GLOB BINDINGS_HEADERS ./*.hpp)
file(GLOB BINDINGS_SOURCES src/vision_api/*.cpp)
file(GLOB BINDINGS_HEADERS src/vision_api/*.hpp)

nanobind_add_module(py_model_api NB_STATIC STABLE_ABI LTO ${BINDINGS_SOURCES} ${BINDINGS_HEADERS})
message(INFO ${BINDINGS_SOURCES})

target_link_libraries(py_model_api PRIVATE model_api)
nanobind_add_module(_vision_api NB_STATIC STABLE_ABI LTO ${BINDINGS_SOURCES} ${BINDINGS_HEADERS})

nanobind_add_stub(
py_model_api_stub
MODULE py_model_api
OUTPUT py_model_api.pyi
PYTHON_PATH $<TARGET_FILE_DIR:py_model_api>
DEPENDS py_model_api
set_target_properties(_vision_api PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src/vision_api"
Copy link
Member

@sovrasov sovrasov Apr 16, 2025

Choose a reason for hiding this comment

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

Binaries are dumped to the source dir, which looks a bit weird. Can we use the build dir for that?

)

target_link_libraries(_vision_api PRIVATE model_api)

include(opencv.cmake)
28 changes: 28 additions & 0 deletions src/cpp/py_bindings/opencv.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
find_package(OpenCV REQUIRED COMPONENTS core imgproc)

if (MSVC)
set(DEPENDENCIES_TO_COPY
"${__location_release}"
)
else()
find_package(PkgConfig REQUIRED)
find_package(TBB "2021.5.0" EXACT REQUIRED)
pkg_check_modules(TBB REQUIRED tbb)

set(DEPENDENCIES_TO_COPY
${OpenCV_DIR}/../../libopencv_core.so.4.5d
${OpenCV_DIR}/../../libopencv_imgproc.so.4.5d
${pkgcfg_lib_TBB_tbb}.2 # ubuntu system package uses tbb.so.2
)
endif()

set(PYTHON_PACKAGE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/vision_api)
foreach(lib ${DEPENDENCIES_TO_COPY})
add_custom_command(
TARGET _vision_api POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${lib}
${PYTHON_PACKAGE_DIR}
COMMENT "Copying ${lib} to ${PYTHON_PACKAGE_DIR}"
)
endforeach()
32 changes: 32 additions & 0 deletions src/cpp/py_bindings/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[build-system]
requires = ["scikit-build-core >=0.4.3", "nanobind >=1.3.2"]
build-backend = "scikit_build_core.build"

[project]
name = "vision_api"
version = "0.3.0.2"
requires-python = ">=3.9"
authors = [
{name = "Intel(R) Corporation"},
]
maintainers = [
{name = "Intel(R) Corporation"},
]
description = "Model API: model wrappers and pipelines for inference with OpenVINO"
readme = "../../python/README.md"
classifiers = [
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3.9"
]

[project.urls]
Homepage = "https://github.com/open-edge-platform/model_api"

[tool.scikit-build]
# Protect the configuration against future changes in scikit-build-core
minimum-version = "0.4"
# Setuptools-style build caching in a local directory
build-dir = "build/{wheel_tag}"
# Build stable ABI wheels for CPython 3.12+
wheel.py-api = "cp312"
sdist.include = ["*.so*"]
16 changes: 16 additions & 0 deletions src/cpp/py_bindings/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env python3
Copy link
Member

@sovrasov sovrasov Apr 15, 2025

Choose a reason for hiding this comment

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

Do we actually need that sample? Can be moved to tests as well


from vision_api import ClassificationModel
import cv2

import sys

if len(sys.argv) != 3:
raise RuntimeError(f"Usage: {sys.argv[0]} <path_to_model> <path_to_image>")

model_path = sys.argv[1]
image_path = sys.argv[2]

model = ClassificationModel.create_model(model_path)
image = cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_BGR2RGB)
model(image)
13 changes: 13 additions & 0 deletions src/cpp/py_bindings/src/vision_api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

try:
from openvino import Core

_ = Core() # Triggers loading of shared libs like libopenvino.so
except Exception as e:
raise ImportError(f"Failed to initialize OpenVINO runtime: {e}")

from ._vision_api import ClassificationModel

__all__ = [ClassificationModel]
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace nb = nanobind;
void init_classification(nb::module_& m);
void init_base_modules(nb::module_& m);

NB_MODULE(py_model_api, m) {
NB_MODULE(_vision_api, m) {
m.doc() = "Nanobind binding for OpenVINO Vision API library";
init_base_modules(m);
init_classification(m);
Expand Down
1 change: 0 additions & 1 deletion tests/cpp/accuracy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ include(../cmake/common.cmake)

find_package(OpenCV REQUIRED COMPONENTS core highgui videoio imgproc imgcodecs)

set(ENABLE_PY_BINDINGS OFF)
add_subdirectory(../../../src/cpp ${tests_BINARY_DIR}/model_api/cpp)

add_test(NAME test_accuracy SOURCES test_accuracy.cpp DEPENDENCIES model_api)
Expand Down
9 changes: 9 additions & 0 deletions tests/cpp/accuracy/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#
# Copyright (C) 2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#


def pytest_addoption(parser):
parser.addoption("--data", action="store", help="data folder with dataset")
parser.addoption("--config", action="store", help="path to models config")
56 changes: 56 additions & 0 deletions tests/cpp/accuracy/test_bindings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#
# Copyright (C) 2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#

import pytest
import json
from pathlib import Path

import cv2

from model_api.models import Model
from vision_api import ClassificationModel


def read_config(models_config: str, model_type: str):
with open(models_config, "r") as f:
data = json.load(f)
for item in data:
if item["type"] == model_type:
yield item


@pytest.fixture(scope="session")
def data(pytestconfig) -> str:
return pytestconfig.getoption("data")


@pytest.fixture(scope="session")
def models_config(pytestconfig) -> str:
return pytestconfig.getoption("config")


@pytest.fixture()
def classification_configs(models_config: str):
return read_config(models_config, "ClassificationModel")


def test_classification_models(data: str, classification_configs):
for model_data in classification_configs:
name = model_data["name"]
if ".xml" not in name:
continue
if name.endswith(".xml") or name.endswith(".onnx"):
name = f"{data}/{name}"

model = Model.create_model(name, preload=True)
cpp_model = ClassificationModel.create_model(name, preload=True)

image_path = Path(data) / next(iter(model_data["test_data"]))["image"]
image = cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_BGR2RGB)

py_result = model(image)
cpp_result = cpp_model(image)

assert str(py_result) == str(cpp_result)
3 changes: 1 addition & 2 deletions tests/cpp/cmake/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ macro(add_test)
target_link_libraries(${TEST_NAME} PRIVATE pthread)
endif()

target_link_libraries(${TEST_NAME} PRIVATE gtest gtest_main)
target_link_libraries(${TEST_NAME} PRIVATE nlohmann_json::nlohmann_json)
target_link_libraries(${TEST_NAME} PRIVATE gtest_main gmock_main nlohmann_json::nlohmann_json)

endmacro()
1 change: 0 additions & 1 deletion tests/cpp/precommit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ include(../cmake/common.cmake)

find_package(OpenCV REQUIRED COMPONENTS core highgui videoio imgproc imgcodecs)

set(ENABLE_PY_BINDINGS OFF)
add_subdirectory(../../../src/cpp ${tests_BINARY_DIR}/model_api/cpp)

add_test(NAME test_sanity SOURCES test_sanity.cpp DEPENDENCIES model_api)
Expand Down
12 changes: 0 additions & 12 deletions tests/python/accuracy/public_scope.json
Original file line number Diff line number Diff line change
Expand Up @@ -256,18 +256,6 @@
}
]
},
{
"name": "otx_models/mobilenet_v3_large_hc_cf.xml",
"type": "ClassificationModel",
"test_data": [
{
"image": "coco128/images/train2017/000000000081.jpg",
"reference": [
"3 (equilateral): 0.596, 1 (multi a): 0.922, 2 (multi b): 0.696, 5 (triangle): 0.993, [0], [0], [0]"
]
}
]
},
{
"name": "otx_models/classification_model_with_xai_head.xml",
"type": "ClassificationModel",
Expand Down
Loading