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
2 changes: 0 additions & 2 deletions mediapipe/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,6 @@ filegroup(
srcs = [
"//mediapipe/calculators/geti/serialization:calculators",
"//mediapipe/calculators/geti/inference:geti_calculator_base",
"//mediapipe/calculators/geti/inference:grpc_predict_v2_cc_proto",
"//mediapipe/calculators/geti/inference:grpc_predict_v2_proto",
"//mediapipe/calculators/geti/inference:inference_calculators",
"//mediapipe/calculators/geti/inference:inference_utils",
"//mediapipe/calculators/geti/inference:openvino_inference_adapter_calculator_cc_proto",
Expand Down
13 changes: 1 addition & 12 deletions mediapipe/calculators/geti/inference/BUILD
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
load("//mediapipe/framework/port:build_config.bzl", "mediapipe_cc_proto_library", "mediapipe_proto_library")
load("@rules_cc//cc:defs.bzl", "cc_proto_library")

package(default_visibility = ["//visibility:public"])

proto_library(
name = "grpc_predict_v2_proto",
srcs = ["grpc_predict_v2.proto"],
)

cc_proto_library(
name = "grpc_predict_v2_cc_proto",
deps = [":grpc_predict_v2_proto"],
)

proto_library(
name = "openvino_inference_adapter_calculator_proto",
srcs = ["openvino_inference_adapter_calculator.proto"],
Expand Down Expand Up @@ -63,7 +52,7 @@ cc_library(
],
deps = [
":openvino_inference_adapter_calculator_cc_proto",
":grpc_predict_v2_cc_proto",
"@ovms//src/kfserving_api:kfserving_api_cpp",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework/formats:image_frame_opencv",
"//mediapipe/framework/port:opencv_core",
Expand Down
2 changes: 1 addition & 1 deletion mediapipe/calculators/geti/inference/kserve.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#ifndef KSERVE_H
#define KSERVE_H

#include "mediapipe/calculators/geti/inference/grpc_predict_v2.pb.h"
#include "src/kfserving_api/grpc_predict_v2.pb.h"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Does GETI work with current changes with regards to python binding?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Need to test it.


using KFSRequest = inference::ModelInferRequest;
using KFSResponse = inference::ModelInferResponse;
Expand Down
42 changes: 42 additions & 0 deletions mediapipe/calculators/ovms/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,26 @@ cc_library(
alwayslink = 1,
)

cc_library(
name = "ovms_calculator_runtime",
srcs = [
],
deps = [
"//mediapipe/calculators/openvino:openvino_tensors_to_classification_calculator_cc_proto",
"//mediapipe/calculators/openvino:openvino_tensors_to_detections_calculator_cc_proto",
"//mediapipe/calculators/openvino:openvino_converter_calculator_cc_proto",
"//mediapipe/calculators/openvino:openvino_converter_calculator",
"//mediapipe/calculators/openvino:openvino_tensors_to_classification_calculator",
"//mediapipe/calculators/openvino:openvino_tensors_to_detections_calculator",
":modelapiovmsadapter",
":openvinoinferencecalculator_no_tflite",
":openvinomodelserversessioncalculator",
],
copts = ["-Iexternal/ovms/src","-Isrc"],
linkopts = ["-Lmediapipe/"],
alwayslink = 1,
)

cc_library(
name = "modelapiovmsadapter",
srcs = [
Expand Down Expand Up @@ -125,6 +145,28 @@ cc_library(
alwayslink = 1,
)

cc_library(
name = "openvinoinferencecalculator_no_tflite",
srcs = [
"openvinoinferencecalculator.cc",
],
hdrs = [
"openvinoinferencecalculator.h",
],
deps = [
"openvinoinferencecalculatoroptions",
":modelapiovmsadapter",
":openvinoinferencecalculator_cc_proto",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework/formats:tensor",
"//third_party:openvino",
"@ovms//src:ovms_header",
],
copts = ["-Iexternal/ovms/src","-Isrc"],
local_defines = ["OVMS_RUNTIME_DISABLE_TFLITE_TENSORS=1"],
alwayslink = 1,
)

cc_library(
name = "openvinomodelserversessioncalculator",
srcs = [
Expand Down
1 change: 0 additions & 1 deletion mediapipe/calculators/ovms/modelapiovmsadapter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
// for the one inside OVMS repo it makes sense to reuse code from ovms lib
namespace mediapipe::ovms {

using std::endl;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
using InferenceOutput = std::map<std::string, ov::Tensor>;
Expand Down
49 changes: 48 additions & 1 deletion mediapipe/calculators/ovms/modelapiovmsadapter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@
#include <iostream>
#include <map>
#include <memory>
#include <mutex>
#include <cstdio>
#include <sstream>
#include <stdexcept>
#include <string>
#include <thread>
#include <unordered_map>
#include <utility>
#include <vector>
Expand All @@ -28,6 +32,10 @@

#include "ovms.h" // NOLINT

#ifdef _WIN32
#include <Windows.h>
#endif

// here we need to decide if we have several calculators (1 for OVMS repository, 1-N inside mediapipe)
// for the one inside OVMS repo it makes sense to reuse code from ovms lib

Expand All @@ -54,6 +62,45 @@ class OVMSInferenceAdapter : public ::InferenceAdapter {
std::unordered_map<std::string, ov::element::Type_t> outputDatatypes;
ov::AnyMap modelConfig;

// Creates (once per process) and returns a shared OVMS server handle for adapters
// that are constructed without an explicit server pointer.
// This path is used by calculators running in-process when they rely on the default
// OVMS singleton instead of receiving a handle from runtime/shared-library plumbing.
// Keeping one shared handle avoids repeated OVMS_ServerNew calls and keeps all such
// adapters bound to the same server instance.
Comment on lines +65 to +70

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Earlier on the fact the only one server instance existed was due to not creating new server instance in C-API of OVMS. So if the same instance was being created depended entirely on OVMS desing. Now you add this logic also here. Why we could not call serverNewFn multiple times as earlier on?

Calling OVMS_ServerNew should still work the same way anyway. So this brings new unnecessary logic and checks here I think.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

You still can use OVMS_ServerNew — and on Linux with RTLD_GLOBAL it works because symbol resolution finds the main process singleton. The setExternalServerHandle mechanism was added specifically for:

Windows — where GetModuleHandleA("ovms_mediapipe_runtime_shared.dll") + GetProcAddress is the only reliable way to pass a pointer across DLL boundaries.
Deterministic cross-boundary handoff — rather than relying on dlsym(RTLD_DEFAULT, ...) lookup ordering, which can resolve to the wrong copy if both the main binary and the runtime shared library export OVMS_ServerNew.
Issue was found in capi stress test on windows.

static OVMS_Server* getSharedServerHandle() {
static std::once_flag once;
static OVMS_Server* sharedServer{nullptr};
std::fprintf(stderr, "OVMSAdapter shared handle call_once entry thread=%zu\n", std::hash<std::thread::id>{}(std::this_thread::get_id()));
std::call_once(once, []() {
std::fprintf(stderr, "OVMSAdapter shared handle init start\n");
auto* serverNewFn = &OVMS_ServerNew;
std::fprintf(stderr, "OVMSAdapter shared handle OVMS_ServerNew fn=%p\n", reinterpret_cast<void*>(serverNewFn));
#ifdef _WIN32
HMODULE mod = nullptr;
if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
reinterpret_cast<LPCSTR>(serverNewFn), &mod) != 0) {
char modulePath[MAX_PATH] = {0};
DWORD pathLen = GetModuleFileNameA(mod, modulePath, MAX_PATH);
if (pathLen > 0) {
std::fprintf(stderr, "OVMSAdapter shared handle OVMS_ServerNew module=%s\n", modulePath);
}
}
#endif
OVMS_Status* status = serverNewFn(&sharedServer);
std::fprintf(stderr, "OVMSAdapter shared handle init OVMS_ServerNew returned status=%p server=%p\n", static_cast<void*>(status), static_cast<void*>(sharedServer));
if (status != nullptr) {
const char* msg = nullptr;
OVMS_StatusDetails(status, &msg);
std::string details = (msg != nullptr) ? msg : "unknown error";
OVMS_StatusDelete(status);
throw std::runtime_error("OVMS_ServerNew failed in OVMSInferenceAdapter: " + details);
}
});
std::fprintf(stderr, "OVMSAdapter shared handle call_once exit server=%p\n", static_cast<void*>(sharedServer));
return sharedServer;
}

public:
// TODO Windows: Fix definition in header - does not compile in cpp.
OVMSInferenceAdapter(const std::string& servableName, uint32_t servableVersion = 0, OVMS_Server* server = nullptr) :
Expand All @@ -62,7 +109,7 @@ class OVMSInferenceAdapter : public ::InferenceAdapter {
if (nullptr != server) {
this->cserver = server;
} else {
OVMS_ServerNew(&this->cserver);
this->cserver = getSharedServerHandle();
}
}
virtual ~OVMSInferenceAdapter();
Expand Down
Loading