Skip to content
Draft
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: 1 addition & 1 deletion samples/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ macro(ov_add_sample)
if(c_sample)
set(ov_link_libraries openvino::runtime::c)
else()
set(ov_link_libraries openvino::runtime)
set(ov_link_libraries)
endif()

set_target_properties(${SAMPLE_NAME} PROPERTIES FOLDER ${folder_name}
Expand Down
169 changes: 62 additions & 107 deletions samples/cpp/hello_classification/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,120 +7,75 @@
#include <sstream>
#include <string>
#include <vector>
#include <iostream>

#ifdef _WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#endif

// clang-format off
#include "openvino/openvino.hpp"

#include "samples/args_helper.hpp"
#include "samples/common.hpp"
#include "samples/classification_results.h"
#include "samples/slog.hpp"
#include "format_reader_ptr.h"
// clang-format on

/**
* @brief Main with support Unicode paths, wide strings
*/
int tmain(int argc, tchar* argv[]) {
try {
// -------- Set OpenVINO log message capturing callback --------
const std::function<void(std::string_view)> log_callback{[](std::string_view msg) {
slog::info << msg;
}};
ov::util::set_log_callback(log_callback);

// -------- Get OpenVINO runtime version --------
slog::info << ov::get_openvino_version() << slog::endl;

// -------- Parsing and validation of input arguments --------
if (argc != 4) {
slog::info << "Usage : " << TSTRING2STRING(argv[0]) << " <path_to_model> <path_to_image> <device_name>"
<< slog::endl;
return EXIT_FAILURE;
}

const std::string args = TSTRING2STRING(argv[0]);
const std::string model_path = TSTRING2STRING(argv[1]);
const std::string image_path = TSTRING2STRING(argv[2]);
const std::string device_name = TSTRING2STRING(argv[3]);

// -------- Step 1. Initialize OpenVINO Runtime Core --------
ov::Core core;

// -------- Step 2. Read a model --------
slog::info << "Loading model files: " << model_path << slog::endl;
std::shared_ptr<ov::Model> model = core.read_model(model_path);
printInputAndOutputsInfo(*model);

OPENVINO_ASSERT(model->inputs().size() == 1, "Sample supports models with 1 input only");
OPENVINO_ASSERT(model->outputs().size() == 1, "Sample supports models with 1 output only");

// -------- Step 3. Set up input

// Read input image to a tensor and set it to an infer request
// without resize and layout conversions
FormatReader::ReaderPtr reader(image_path.c_str());
if (reader.get() == nullptr) {
std::stringstream ss;
ss << "Image " + image_path + " cannot be read!";
throw std::logic_error(ss.str());
}

ov::element::Type input_type = ov::element::u8;
ov::Shape input_shape = {1, reader->height(), reader->width(), 3};
std::shared_ptr<unsigned char> input_data = reader->getData();

// just wrap image data by ov::Tensor without allocating of new memory
ov::Tensor input_tensor = ov::Tensor(input_type, input_shape, input_data.get());

const ov::Layout tensor_layout{"NHWC"};

// -------- Step 4. Configure preprocessing --------

ov::preprocess::PrePostProcessor ppp(model);

// 1) Set input tensor information:
// - input() provides information about a single model input
// - reuse precision and shape from already available `input_tensor`
// - layout of data is 'NHWC'
ppp.input().tensor().set_shape(input_shape).set_element_type(input_type).set_layout(tensor_layout);
// 2) Adding explicit preprocessing steps:
// - convert layout to 'NCHW' (from 'NHWC' specified above at tensor layout)
// - apply linear resize from tensor spatial dims to model spatial dims
ppp.input().preprocess().resize(ov::preprocess::ResizeAlgorithm::RESIZE_LINEAR);
// 4) Suppose model has 'NCHW' layout for input
ppp.input().model().set_layout("NCHW");
// 5) Set output tensor information:
// - precision of tensor is supposed to be 'f32'
ppp.output().tensor().set_element_type(ov::element::f32);

// 6) Apply preprocessing modifying the original 'model'
model = ppp.build();

// -------- Step 5. Loading a model to the device --------
ov::CompiledModel compiled_model = core.compile_model(model, device_name);

// -------- Step 6. Create an infer request --------
ov::InferRequest infer_request = compiled_model.create_infer_request();
// -----------------------------------------------------------------------------------------------------

// -------- Step 7. Prepare input --------
infer_request.set_input_tensor(input_tensor);

// -------- Step 8. Do inference synchronously --------
infer_request.infer();

// -------- Step 9. Process output
const ov::Tensor& output_tensor = infer_request.get_output_tensor();

// Print classification results
ClassificationResult classification_result(output_tensor, {image_path});
classification_result.show();
// -----------------------------------------------------------------------------------------------------
} catch (const std::exception& ex) {
std::cerr << ex.what() << std::endl;
return EXIT_FAILURE;
int main() {

std::cout << "Hello Classification Sample" << std::endl;

#ifdef _WIN32
// Path to the shared library
const char* lib_path = "openvino.dll";

// Load the shared library
std::cout << "Loading shared library: " << lib_path << std::endl;
HMODULE handle = LoadLibraryA(lib_path);

if (!handle) {
std::cerr << "Error loading library: " << GetLastError() << std::endl;
return 1;
}

return EXIT_SUCCESS;

std::cout << "Library loaded successfully!" << std::endl;

// Unload the shared library
std::cout << "Unloading shared library..." << std::endl;
if (!FreeLibrary(handle)) {
std::cerr << "Error unloading library: " << GetLastError() << std::endl;
return 1;
}

std::cout << "Library unloaded successfully!" << std::endl;
#else
// Path to the shared library
const char* lib_path = "libopenvino.so";

// Load the shared library
std::cout << "Loading shared library: " << lib_path << std::endl;
void* handle = dlopen(lib_path, RTLD_LAZY);

if (!handle) {
std::cerr << "Error loading library: " << dlerror() << std::endl;
return 1;
}

std::cout << "Library loaded successfully!" << std::endl;

// Clear any existing error
dlerror();

// Unload the shared library
std::cout << "Unloading shared library..." << std::endl;
if (dlclose(handle) != 0) {
std::cerr << "Error unloading library: " << dlerror() << std::endl;
return 1;
}

std::cout << "Library unloaded successfully!" << std::endl;
#endif

return 0;
}
1 change: 1 addition & 0 deletions src/cmake/openvino.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ target_include_directories(${TARGET_NAME} INTERFACE
target_link_libraries(${TARGET_NAME}
PRIVATE openvino::reference
openvino::shape_inference
openvino::shutdown
openvino::pugixml
${CMAKE_DL_LIBS}
Threads::Threads
Expand Down
2 changes: 2 additions & 0 deletions src/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
#

add_subdirectory(itt)
add_subdirectory(shutdown)
add_subdirectory(conditional_compilation)
add_subdirectory(util)
add_subdirectory(test_lib)

if(ENABLE_INTEL_CPU)
add_subdirectory(snippets)
Expand Down
3 changes: 3 additions & 0 deletions src/common/itt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ if(NOT ENABLE_PROFILING_ITT STREQUAL "OFF")
endif()
endif()

target_include_directories(${TARGET_NAME} PRIVATE
$<TARGET_PROPERTY:openvino::shutdown,INTERFACE_INCLUDE_DIRECTORIES>)

target_include_directories(${TARGET_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)

Expand Down
12 changes: 12 additions & 0 deletions src/common/itt/src/itt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
#include <cstdlib>
#include <mutex>
#include <vector>
#include <iostream>

#include "shutdown.hpp"

#ifdef ENABLE_PROFILING_ITT
# include <ittnotify.h>
Expand Down Expand Up @@ -133,3 +136,12 @@ void regionEnd(domain_t) {}
} // namespace internal
} // namespace itt
} // namespace openvino


static void shutdown_itt_resources() {
std::cout << "Shutdown ITT: Releasing ITT resources..." << std::endl;
}

extern "C" void itt_shutdown() {
shutdown_itt_resources();
}
21 changes: 21 additions & 0 deletions src/common/shutdown/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright (C) 2026 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#

set(TARGET_NAME openvino_shutdown)

# Main shutdown library without weak symbols
add_library(${TARGET_NAME} OBJECT shutdown.cpp)
add_library(openvino::shutdown ALIAS ${TARGET_NAME})
target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(${TARGET_NAME} PROPERTIES EXPORT_NAME openvino_shutdown)


# Separate library for weak default implementations - must be linked AFTER itt
set(WEAK_TARGET_NAME openvino_shutdown_weak)
add_library(${WEAK_TARGET_NAME} STATIC unload_weak_defs.cpp)
add_library(openvino::shutdown_weak ALIAS ${WEAK_TARGET_NAME})
target_include_directories(${WEAK_TARGET_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(${WEAK_TARGET_NAME} PROPERTIES EXPORT_NAME openvino_shutdown_weak)

target_link_libraries(${TARGET_NAME} PRIVATE ${WEAK_TARGET_NAME})
43 changes: 43 additions & 0 deletions src/common/shutdown/shutdown.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (C) 2026 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "shutdown.hpp"

#include <iostream>
#include <mutex>
#include <vector>

namespace {
void call_on_unload() {
itt_shutdown();
test_lib_shutdown();
}
} // namespace init_registry



#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__MINGW64__)
# include <windows.h>
BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved) // reserved
{
// Perform actions based on the reason for calling.
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;

case DLL_PROCESS_DETACH:
call_on_unload();
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
#elif defined(__linux__) || defined(__APPLE__) || defined(__EMSCRIPTEN__)
extern "C" __attribute__((destructor)) void library_unload();
void library_unload() {
call_on_unload();
}
#endif
27 changes: 27 additions & 0 deletions src/common/shutdown/shutdown.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) 2026 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

namespace init_registry {
} // namespace init_registry

#if defined(_MSC_VER)

extern "C" void itt_shutdown();
#pragma comment(linker, "/alternatename:itt_shutdown=itt_shutdown_default")

extern "C" void test_lib_shutdown();
#pragma comment(linker, "/alternatename:test_lib_shutdown=test_lib_shutdown_default")

#elif defined(__GNUC__) || defined(__clang__)
extern "C" void itt_shutdown();
extern "C" void test_lib_shutdown();


#else
# error "Compiler not supported"
#endif


34 changes: 34 additions & 0 deletions src/common/shutdown/unload_weak_defs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (C) 2026 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "shutdown.hpp"

#include <iostream>



#if defined(_MSC_VER)

extern "C" void itt_shutdown_default() {
std::cout << "Default itt_shutdown called: no ITT resources to release." << std::endl;
}

extern "C" void test_lib_shutdown_default() {
std::cout << "Default test_lib_shutdown called: no test library resources to release." << std::endl;
}

#elif defined(__GNUC__) || defined(__clang__)
extern "C" void itt_shutdown() __attribute__((weak));

extern "C" void itt_shutdown() {
std::cout << "Default itt_shutdown called: no ITT resources to release." << std::endl;
}

extern "C" void test_lib_shutdown() __attribute__((weak));

extern "C" void test_lib_shutdown() {
std::cout << "Default test_lib_shutdown called: no test library resources to release." << std::endl;
}
#else
# error "Compiler not supported"
#endif
17 changes: 17 additions & 0 deletions src/common/test_lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (C) 2018-2026 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#

set(TARGET_NAME test_lib)

add_library(${TARGET_NAME} STATIC test_lib.cpp)
target_include_directories(${TARGET_NAME} PRIVATE
$<TARGET_PROPERTY:openvino::shutdown,INTERFACE_INCLUDE_DIRECTORIES>)

set_target_properties(${TARGET_NAME} PROPERTIES EXPORT_NAME test_lib)

ov_install_static_lib(${TARGET_NAME} ${OV_CPACK_COMP_CORE})

ov_developer_package_export_targets(TARGET test_lib
INSTALL_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/include/")

8 changes: 8 additions & 0 deletions src/common/test_lib/test_lib.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <iostream>


#include "shutdown.hpp"

extern "C" void test_lib_shutdown() {
std::cout << "Test library shutdown: Releasing test library resources..." << std::endl;
}
Loading