From a042ff2cf9e036ae00d3013c2c93cf524f2cee07 Mon Sep 17 00:00:00 2001 From: Pawel Date: Thu, 11 Dec 2025 11:33:41 +0100 Subject: [PATCH 01/16] save --- src/modelinstance.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/modelinstance.cpp b/src/modelinstance.cpp index 5ace88e1bf..97c06a1c79 100644 --- a/src/modelinstance.cpp +++ b/src/modelinstance.cpp @@ -230,6 +230,14 @@ const Layout ModelInstance::getReportedTensorLayout(const ModelConfig& config, c return defaultLayout; } +static Status applyPreprocessingConfiguration(const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion) { + OV_LOGGER("ov::Model: {}, ov::preprocess::PrePostProcessor(ov::Model)", reinterpret_cast(model.get())); + ov::preprocess::PrePostProcessor preproc(model); + + + return StatusCode::OK; +} + static Status applyLayoutConfiguration(const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion) { OV_LOGGER("ov::Model: {}, ov::preprocess::PrePostProcessor(ov::Model)", reinterpret_cast(model.get())); ov::preprocess::PrePostProcessor preproc(model); From eb04d49de8957ea04ace1da96da35431b961da69 Mon Sep 17 00:00:00 2001 From: Pawel Date: Mon, 29 Dec 2025 13:08:04 +0100 Subject: [PATCH 02/16] save --- src/modelinstance.cpp | 87 +++++++++++++++++++++++++++++++++---------- src/modelinstance.hpp | 9 ++++- 2 files changed, 76 insertions(+), 20 deletions(-) diff --git a/src/modelinstance.cpp b/src/modelinstance.cpp index 97c06a1c79..5da63f92e7 100644 --- a/src/modelinstance.cpp +++ b/src/modelinstance.cpp @@ -230,18 +230,43 @@ const Layout ModelInstance::getReportedTensorLayout(const ModelConfig& config, c return defaultLayout; } -static Status applyPreprocessingConfiguration(const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion) { - OV_LOGGER("ov::Model: {}, ov::preprocess::PrePostProcessor(ov::Model)", reinterpret_cast(model.get())); - ov::preprocess::PrePostProcessor preproc(model); - +static Status applyPreprocessingConfiguration(ov::preprocess::PrePostProcessor& preproc, const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion) { + OV_LOGGER("ov::preprocess::PrePostProcessor& preproc, const ModelConfig& config, std::shared_ptr& model"); + //resnet onnx model specific preprocessing + std::vector scaleValues = { 58.395f, 57.12f, 57.375f }; + std::vector meanValues = { 123.675f, 116.28f, 103.53f }; + + std::variant,float> preprocessingScale = scaleValues;// to be overridden by config + std::variant,float> preprocessingMean = meanValues;// to be overridden by config + ov::preprocess::ColorFormat colorFormat = ov::preprocess::ColorFormat::RGB; // to be overridden by config + + // if(std::get_if>(preprocessingScale).has_value()) { { + // preprocessingScale = config.getPreprocessingScale(); + // } else if (std::get_if(preprocessingScale).has_value()) { + // preprocessingScale = std::get(config.getPreprocessingScale()); + // } else { + // SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Using default preprocessing scale"); + // } + + // if (std::get_if>(preprocessingMean).has_value()) { + // preprocessingMean = config.getPreprocessingMean(); + // } else if (std::get_if(preprocessingMean).has_value()) { + // preprocessingMean = std::get(config.getPreprocessingMean()); + // } else { + // SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Using default preprocessing mean"); + // } + + preproc.input("data").tensor().set_color_format(colorFormat); + + preproc.input("data").preprocess() + .mean(std::get>(preprocessingMean)) + .scale(std::get>(preprocessingScale)) + .convert_color(colorFormat); return StatusCode::OK; } -static Status applyLayoutConfiguration(const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion) { - OV_LOGGER("ov::Model: {}, ov::preprocess::PrePostProcessor(ov::Model)", reinterpret_cast(model.get())); - ov::preprocess::PrePostProcessor preproc(model); - +static Status applyLayoutConfiguration(ov::preprocess::PrePostProcessor& preproc, const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion) { SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Applying layout configuration: {}", config.layoutConfigurationToString()); OV_LOGGER("ov::Model: {}, model->inputs()", reinterpret_cast(model.get())); @@ -362,13 +387,40 @@ static Status applyLayoutConfiguration(const ModelConfig& config, std::shared_pt } } + return StatusCode::OK; +} + +Status ModelInstance::applyPreprocessing(const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion){ + OV_LOGGER("ov::Model: {}, ov::preprocess::PrePostProcessor(ov::Model)", reinterpret_cast(model.get())); + SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Applying preprocessing configuration"); + ov::preprocess::PrePostProcessor preproc(model); + Status status = StatusCode::OK; + + // bool hasLayoutConfigChanged = !config.isLayoutConfigurationEqual(this->config); + // bool needsToApplyLayoutConfiguration = hasLayoutConfigChanged || !this->model; + + // if (needsToApplyLayoutConfiguration) { + SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Applying layout configuration"); + status = applyLayoutConfiguration(preproc, config, model, modelName, modelVersion); + if (!status.ok()) { + return status; + } + // } + + status = applyPreprocessingConfiguration(preproc, config, model, modelName, modelVersion);//there should be also condition + if (!status.ok()) { + SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during preprocessing configuration"); + return status; + } + try { OV_LOGGER("preproc: {}, ov::Model = ov::preprocess::PrePostProcessor::build()", reinterpret_cast(&preproc)); model = preproc.build(); - } catch (std::exception&) { - SPDLOG_LOGGER_ERROR(modelmanager_logger, "Cannot change layout"); + } catch (std::exception& e) { + SPDLOG_LOGGER_ERROR(modelmanager_logger, "Cannot change layout or preprocessing parameters. Error: {}", e.what()); return StatusCode::MODEL_NOT_LOADED; } + return StatusCode::OK; } @@ -438,7 +490,7 @@ Status ModelInstance::adjustForEmptyOutputNames() { return StatusCode::OK; } -Status ModelInstance::loadTensors(const ModelConfig& config, bool needsToApplyLayoutConfiguration, const DynamicModelParameter& parameter) { +Status ModelInstance::loadTensors(const ModelConfig& config, const DynamicModelParameter& parameter) { Status status = validateConfigurationAgainstNetwork(config, this->model); if (!status.ok()) { SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during configuration validation against model"); @@ -449,12 +501,10 @@ Status ModelInstance::loadTensors(const ModelConfig& config, bool needsToApplyLa SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during adjusting output names"); return status; } - if (needsToApplyLayoutConfiguration) { - status = applyLayoutConfiguration(config, this->model, getName(), getVersion()); - if (!status.ok()) { - SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during layout configuration"); - return status; - } + status = applyPreprocessing(config, this->model, getName(), getVersion()); + if (!status.ok()) { + SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during layout/preprocessing configuration"); + return status; } status = loadInputTensors(config, parameter); if (!status.ok()) { @@ -972,7 +1022,6 @@ void ModelInstance::loadTensorFactories() { Status ModelInstance::loadModelImpl(const ModelConfig& config, const DynamicModelParameter& parameter) { bool isLayoutConfigurationChanged = !config.isLayoutConfigurationEqual(this->config); - bool needsToApplyLayoutConfiguration = isLayoutConfigurationChanged || !this->model; subscriptionManager.notifySubscribers(); this->path = config.getPath(); @@ -1004,7 +1053,7 @@ Status ModelInstance::loadModelImpl(const ModelConfig& config, const DynamicMode return status; } - status = loadTensors(this->config, needsToApplyLayoutConfiguration, parameter); + status = loadTensors(this->config, parameter); if (!status.ok()) { this->status.setLoading(ModelVersionStatusErrorCode::UNKNOWN); return status; diff --git a/src/modelinstance.hpp b/src/modelinstance.hpp index 541deb5f13..9e9c9d3afe 100644 --- a/src/modelinstance.hpp +++ b/src/modelinstance.hpp @@ -306,7 +306,14 @@ class ModelInstance : public Servable { * * @param config */ - Status loadTensors(const ModelConfig& config, bool needsToApplyLayoutConfiguration, const DynamicModelParameter& parameter = DynamicModelParameter()); + Status loadTensors(const ModelConfig& config, const DynamicModelParameter& parameter = DynamicModelParameter()); + + /** + * @brief Internal method for preprocessing model + * + * @param config + */ + Status applyPreprocessing(const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion); /** * @brief Internal method for loading inputs From 67db6943fa0594c3d8e02bc0e71d2ac3ce97d9ca Mon Sep 17 00:00:00 2001 From: Pawel Date: Tue, 30 Dec 2025 13:47:26 +0100 Subject: [PATCH 03/16] save --- src/capi_frontend/server_settings.hpp | 2 + src/cli_parser.cpp | 10 +++++ src/config.cpp | 2 + src/config.hpp | 15 ++++++- src/modelconfig.cpp | 64 +++++++++++++++++++++++++++ src/modelconfig.hpp | 60 +++++++++++++++++++++++++ src/modelinstance.cpp | 14 ++++-- src/modelmanager.cpp | 12 +++++ src/status.hpp | 1 + 9 files changed, 175 insertions(+), 5 deletions(-) diff --git a/src/capi_frontend/server_settings.hpp b/src/capi_frontend/server_settings.hpp index 3078aa7d9d..ed1dd260e3 100644 --- a/src/capi_frontend/server_settings.hpp +++ b/src/capi_frontend/server_settings.hpp @@ -216,6 +216,8 @@ struct ModelsSettingsImpl { std::string batchSize; std::string shape; std::string layout; + std::string mean; + std::string scale; std::string modelVersionPolicy; uint32_t nireq = 0; std::string targetDevice; diff --git a/src/cli_parser.cpp b/src/cli_parser.cpp index 9eb6219a0b..401dd1e305 100644 --- a/src/cli_parser.cpp +++ b/src/cli_parser.cpp @@ -587,6 +587,16 @@ void CLIParser::prepareModel(ModelsSettingsImpl& modelsSettings, HFSettingsImpl& modelsSettings.userSetSingleModelArguments.push_back("layout"); } + if (result->count("mean")) { + modelsSettings.mean = result->operator[]("mean").as(); + modelsSettings.userSetSingleModelArguments.push_back("mean"); + } + + if (result->count("scale")) { + modelsSettings.scale = result->operator[]("scale").as(); + modelsSettings.userSetSingleModelArguments.push_back("scale"); + } + if (result->count("model_version_policy")) { modelsSettings.modelVersionPolicy = result->operator[]("model_version_policy").as(); modelsSettings.userSetSingleModelArguments.push_back("model_version_policy"); diff --git a/src/config.cpp b/src/config.cpp index 9e780b8f9a..aea0675c37 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -377,6 +377,8 @@ const std::string& Config::batchSize() const { } const std::string& Config::Config::shape() const { return this->modelsSettings.shape; } const std::string& Config::layout() const { return this->modelsSettings.layout; } +const std::string& Config::means() const { return this->modelsSettings.mean; } +const std::string& Config::scales() const { return this->modelsSettings.scale; } const std::string& Config::modelVersionPolicy() const { return this->modelsSettings.modelVersionPolicy; } uint32_t Config::nireq() const { return this->modelsSettings.nireq; } const std::string& Config::targetDevice() const { diff --git a/src/config.hpp b/src/config.hpp index ea29217aaf..fe7b3aec84 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -193,12 +193,25 @@ class Config { const std::string& shape() const; /** - * @brief Get the layout + * @brief Get the sout * * @return const std::string& */ const std::string& layout() const; + /** + * @brief Get means + * + * @return const std::string& + */ + const std::string& means() const; + /** + * @brief Get scales + * + * @return const std::string& + */ + const std::string& scales() const; + /** * @brief Get the shape * diff --git a/src/modelconfig.cpp b/src/modelconfig.cpp index 02850c3188..cc7c34aeda 100644 --- a/src/modelconfig.cpp +++ b/src/modelconfig.cpp @@ -405,6 +405,70 @@ Status ModelConfig::parseLayoutParameter(const std::string& command) { return parseLayoutParameter(node); } +Status ModelConfig::parseFloat(const std::string& str, float& value) { + try { + value = std::stof(str); + } catch (const std::invalid_argument&) { + SPDLOG_WARN("Parameter contains invalid float value: {}", str); + return StatusCode::FLOAT_WRONG_FORMAT; + } catch (const std::out_of_range&) { + SPDLOG_WARN("Parameter contains out of range float value: {}", str); + return StatusCode::FLOAT_WRONG_FORMAT; + } + return StatusCode::OK; +} + +Status ModelConfig::parseFloatArray(const std::string& str, std::vector& values) { + values.clear(); + std::string s = str; + std::stringstream ss(s); + std::string item; + while (std::getline(ss, item, ',')) { + auto status = parseFloat(item, values.emplace_back()); + if (!status.ok()) { + return status; + } + } + return StatusCode::OK; +} + +Status ModelConfig::parseFloatArrayOrValue(const std::string& str, std::variant, float>& values) { + if (str.empty()) { + return StatusCode::OK; + } + + std::string upperCaseCommand; + std::transform(str.begin(), str.end(), std::back_inserter(upperCaseCommand), ::toupper); + + erase_spaces(upperCaseCommand); + + if (*upperCaseCommand.begin() == '{' && *upperCaseCommand.rbegin() == '}') { + auto commandWithoutBraces = upperCaseCommand.substr(1, upperCaseCommand.size() - 2); + std::vector vals; + auto status = parseFloatArray(commandWithoutBraces, vals); + if (!status.ok()) { + return status; + } + values = vals; + return StatusCode::OK; + } + float val; + auto status = parseFloat(upperCaseCommand, val); + if (!status.ok()) { + return status; + } + values = val; + return StatusCode::OK; +} + +Status ModelConfig::parseMean(const std::string& command) { + return parseFloatArrayOrValue(command, this->meanValues); +} + +Status ModelConfig::parseScale(const std::string& command) { + return parseFloatArrayOrValue(command, this->scaleValues); +} + Status ModelConfig::parseShape(ShapeInfo& shapeInfo, const std::string& str) { if (str == "auto") { SPDLOG_LOGGER_WARN(modelmanager_logger, "Shape auto is deprecated. Use model dynamic shapes instead. Check (https://docs.openvino.ai/2023.3/ovms_docs_dynamic_shape_dynamic_model.html#doxid-ovms-docs-dynamic-shape-dynamic-model)"); diff --git a/src/modelconfig.hpp b/src/modelconfig.hpp index 55b5174db2..1949d52622 100644 --- a/src/modelconfig.hpp +++ b/src/modelconfig.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #pragma warning(push) #pragma warning(disable : 6313) #include @@ -200,6 +201,17 @@ class ModelConfig { */ std::string customLoaderOptionsStr; + /** + * @brief meanValues mean preprocessing parameters + */ + std::variant, float> meanValues; + + /** + * @brief scaleValues scale preprocessing parameters + */ + std::variant, float> scaleValues; + + public: /** * @brief Construct a new Model Config object @@ -667,6 +679,54 @@ class ModelConfig { */ Status parseLayoutParameter(const std::string& command); + /** + * @brief Parses value from string and extracts means info + * + * @param string + * + * @return status + */ + Status parseMean(const std::string& command); + + /** + * @brief Parses value from string and extracts scales info + * + * @param string + * + * @return status + */ + Status parseScale(const std::string& command); + + /** + * @brief Parses value from string and extracts float value + * + * @param string + * @param value + * + * @return status + */ + Status parseFloat(const std::string& str, float& value); + + /** + * @brief Parses value from string and extracts float value or array of float values + * + * @param string + * @param value + * + * @return status + */ + Status parseFloatArrayOrValue(const std::string& str, std::variant, float>& values); + + /** + * @brief Parses value from string and extracts array of float values + * + * @param string + * @param value + * + * @return status + */ + Status parseFloatArray(const std::string& str, std::vector& values); + /** * @brief Returns true if any input shape specified in shapes map is in AUTO mode * diff --git a/src/modelinstance.cpp b/src/modelinstance.cpp index 5da63f92e7..ff33a7a40d 100644 --- a/src/modelinstance.cpp +++ b/src/modelinstance.cpp @@ -501,10 +501,16 @@ Status ModelInstance::loadTensors(const ModelConfig& config, const DynamicModelP SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during adjusting output names"); return status; } - status = applyPreprocessing(config, this->model, getName(), getVersion()); - if (!status.ok()) { - SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during layout/preprocessing configuration"); - return status; + + bool hasLayoutConfigChanged = !config.isLayoutConfigurationEqual(this->config); + bool needsToApplyLayoutConfiguration = hasLayoutConfigChanged || !this->model; + + if (needsToApplyLayoutConfiguration) { + status = applyPreprocessing(config, this->model, getName(), getVersion()); + if (!status.ok()) { + SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during layout/preprocessing configuration"); + return status; + } } status = loadInputTensors(config, parameter); if (!status.ok()) { diff --git a/src/modelmanager.cpp b/src/modelmanager.cpp index 35e8b9c534..cd7d622ab8 100644 --- a/src/modelmanager.cpp +++ b/src/modelmanager.cpp @@ -311,6 +311,18 @@ Status ModelManager::startFromConfig() { return status; } + status = modelConfig.parseMean(config.means()); + if (!status.ok()) { + SPDLOG_LOGGER_ERROR(modelmanager_logger, "Couldn't parse mean parameter"); + return status; + } + + status = modelConfig.parseScale(config.scales()); + if (!status.ok()) { + SPDLOG_LOGGER_ERROR(modelmanager_logger, "Couldn't parse scale parameter"); + return status; + } + bool batchSizeSet = (modelConfig.getBatchingMode() != FIXED || modelConfig.getBatchSize() != 0); bool shapeSet = (modelConfig.getShapes().size() > 0); diff --git a/src/status.hpp b/src/status.hpp index fee6300d99..c82ca4b4b5 100644 --- a/src/status.hpp +++ b/src/status.hpp @@ -38,6 +38,7 @@ enum class StatusCode { MODELINSTANCE_NOT_FOUND, SHAPE_WRONG_FORMAT, /*!< The provided shape param is in wrong format */ LAYOUT_WRONG_FORMAT, /*!< The provided layout param is in wrong format */ + FLOAT_WRONG_FORMAT, /*!< The provided float param is in wrong format */ DIM_WRONG_FORMAT, /*!< The provided dimension param is in wrong format */ PLUGIN_CONFIG_WRONG_FORMAT, /*!< Plugin config is in wrong format */ PLUGIN_CONFIG_CONFLICTING_PARAMETERS, /*!< Tried to set the same key twice in plugin config */ From 03844228510cfba94e68d46913c5e0ac65d0c078 Mon Sep 17 00:00:00 2001 From: Pawel Date: Fri, 2 Jan 2026 12:36:47 +0100 Subject: [PATCH 04/16] mean and scale - cli params enabled --- src/cli_parser.cpp | 8 +++++++ src/modelconfig.cpp | 16 +++++++++++++- src/modelconfig.hpp | 20 +++++++++++++++--- src/modelinstance.cpp | 49 +++++++++++++++---------------------------- 4 files changed, 57 insertions(+), 36 deletions(-) diff --git a/src/cli_parser.cpp b/src/cli_parser.cpp index 401dd1e305..cf0cf18f20 100644 --- a/src/cli_parser.cpp +++ b/src/cli_parser.cpp @@ -259,6 +259,14 @@ std::variant> CLIParser::parse(int argc, char* "Resets model layout.", cxxopts::value(), "LAYOUT") + ("mean", + "Resets model mean.", + cxxopts::value(), + "MEAN") + ("scale", + "Resets model scale.", + cxxopts::value(), + "SCALE") ("model_version_policy", "Model version policy", cxxopts::value(), diff --git a/src/modelconfig.cpp b/src/modelconfig.cpp index cc7c34aeda..b600c4313a 100644 --- a/src/modelconfig.cpp +++ b/src/modelconfig.cpp @@ -432,7 +432,7 @@ Status ModelConfig::parseFloatArray(const std::string& str, std::vector& return StatusCode::OK; } -Status ModelConfig::parseFloatArrayOrValue(const std::string& str, std::variant, float>& values) { +Status ModelConfig::parseFloatArrayOrValue(const std::string& str, float_map_or_value_t& values) { if (str.empty()) { return StatusCode::OK; } @@ -637,6 +637,20 @@ Status ModelConfig::parseNode(const rapidjson::Value& v) { } } + if (v.HasMember("mean")) { + Status status = this->parseMean(v["mean"].GetString()); + if (!status.ok()) { + return status; + } + } + + if (v.HasMember("scale")) { + Status status = this->parseMean(v["scale"].GetString()); + if (!status.ok()) { + return status; + } + } + if (v.HasMember("plugin_config")) { auto status = this->parsePluginConfig(v["plugin_config"], this->pluginConfig); if (!status.ok()) { diff --git a/src/modelconfig.hpp b/src/modelconfig.hpp index 1949d52622..069d9af2f1 100644 --- a/src/modelconfig.hpp +++ b/src/modelconfig.hpp @@ -42,6 +42,7 @@ class ModelVersionPolicy; using mapping_config_t = std::unordered_map; using plugin_config_t = std::map; using custom_loader_options_config_t = std::map; +using float_map_or_value_t = std::variant, float>; extern const std::string MAPPING_CONFIG_JSON; const uint32_t DEFAULT_MAX_SEQUENCE_NUMBER = 500; @@ -204,12 +205,12 @@ class ModelConfig { /** * @brief meanValues mean preprocessing parameters */ - std::variant, float> meanValues; + float_map_or_value_t meanValues; /** * @brief scaleValues scale preprocessing parameters */ - std::variant, float> scaleValues; + float_map_or_value_t scaleValues; public: @@ -715,7 +716,7 @@ class ModelConfig { * * @return status */ - Status parseFloatArrayOrValue(const std::string& str, std::variant, float>& values); + Status parseFloatArrayOrValue(const std::string& str, float_map_or_value_t& values); /** * @brief Parses value from string and extracts array of float values @@ -847,6 +848,19 @@ class ModelConfig { this->layout = LayoutConfiguration(); } + const float_map_or_value_t& getScales() const { + return this->scaleValues; + } + + /** + * @brief Get the get means + * + * @return const model_version_t& + */ + const float_map_or_value_t& getMeans() const { + return this->meanValues; + } + /** * @brief Get the version * diff --git a/src/modelinstance.cpp b/src/modelinstance.cpp index ff33a7a40d..65493866b7 100644 --- a/src/modelinstance.cpp +++ b/src/modelinstance.cpp @@ -233,28 +233,17 @@ const Layout ModelInstance::getReportedTensorLayout(const ModelConfig& config, c static Status applyPreprocessingConfiguration(ov::preprocess::PrePostProcessor& preproc, const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion) { OV_LOGGER("ov::preprocess::PrePostProcessor& preproc, const ModelConfig& config, std::shared_ptr& model"); //resnet onnx model specific preprocessing - std::vector scaleValues = { 58.395f, 57.12f, 57.375f }; - std::vector meanValues = { 123.675f, 116.28f, 103.53f }; + // std::vector scaleValues = { 58.395f, 57.12f, 57.375f }; + // std::vector meanValues = { 123.675f, 116.28f, 103.53f }; - std::variant,float> preprocessingScale = scaleValues;// to be overridden by config - std::variant,float> preprocessingMean = meanValues;// to be overridden by config + auto preprocessingScale = config.getScales(); + auto preprocessingMean = config.getMeans(); ov::preprocess::ColorFormat colorFormat = ov::preprocess::ColorFormat::RGB; // to be overridden by config - - // if(std::get_if>(preprocessingScale).has_value()) { { - // preprocessingScale = config.getPreprocessingScale(); - // } else if (std::get_if(preprocessingScale).has_value()) { - // preprocessingScale = std::get(config.getPreprocessingScale()); - // } else { - // SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Using default preprocessing scale"); - // } - // if (std::get_if>(preprocessingMean).has_value()) { - // preprocessingMean = config.getPreprocessingMean(); - // } else if (std::get_if(preprocessingMean).has_value()) { - // preprocessingMean = std::get(config.getPreprocessingMean()); - // } else { - // SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Using default preprocessing mean"); - // } + auto debugPtr = std::get>(preprocessingMean); + for (const auto val : debugPtr) { + SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Using mean array value: {}", val); + } preproc.input("data").tensor().set_color_format(colorFormat); @@ -396,16 +385,12 @@ Status ModelInstance::applyPreprocessing(const ModelConfig& config, std::shared_ ov::preprocess::PrePostProcessor preproc(model); Status status = StatusCode::OK; - // bool hasLayoutConfigChanged = !config.isLayoutConfigurationEqual(this->config); - // bool needsToApplyLayoutConfiguration = hasLayoutConfigChanged || !this->model; - // if (needsToApplyLayoutConfiguration) { - SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Applying layout configuration"); - status = applyLayoutConfiguration(preproc, config, model, modelName, modelVersion); - if (!status.ok()) { - return status; - } - // } + SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Applying layout configuration"); + status = applyLayoutConfiguration(preproc, config, model, modelName, modelVersion); + if (!status.ok()) { + return status; + } status = applyPreprocessingConfiguration(preproc, config, model, modelName, modelVersion);//there should be also condition if (!status.ok()) { @@ -502,16 +487,16 @@ Status ModelInstance::loadTensors(const ModelConfig& config, const DynamicModelP return status; } - bool hasLayoutConfigChanged = !config.isLayoutConfigurationEqual(this->config); - bool needsToApplyLayoutConfiguration = hasLayoutConfigChanged || !this->model; + // bool hasLayoutConfigChanged = !config.isLayoutConfigurationEqual(this->config); + // bool needsToApplyLayoutConfiguration = hasLayoutConfigChanged || !this->model; - if (needsToApplyLayoutConfiguration) { + // if (needsToApplyLayoutConfiguration) { status = applyPreprocessing(config, this->model, getName(), getVersion()); if (!status.ok()) { SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during layout/preprocessing configuration"); return status; } - } + // } status = loadInputTensors(config, parameter); if (!status.ok()) { SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during loading input tensors"); From 613deae4dfe0aab4e26e0d639faf4ebecea115a0 Mon Sep 17 00:00:00 2001 From: Pawel Date: Fri, 2 Jan 2026 13:46:08 +0100 Subject: [PATCH 05/16] adding color format --- src/capi_frontend/server_settings.hpp | 1 + src/cli_parser.cpp | 9 ++++++ src/config.cpp | 1 + src/config.hpp | 7 +++++ src/modelconfig.cpp | 43 +++++++++++++++++++++++++-- src/modelconfig.hpp | 42 +++++++++++++++++++++----- src/modelinstance.cpp | 10 +------ src/modelmanager.cpp | 6 ++++ src/status.hpp | 1 + 9 files changed, 102 insertions(+), 18 deletions(-) diff --git a/src/capi_frontend/server_settings.hpp b/src/capi_frontend/server_settings.hpp index ed1dd260e3..5c9a811e03 100644 --- a/src/capi_frontend/server_settings.hpp +++ b/src/capi_frontend/server_settings.hpp @@ -218,6 +218,7 @@ struct ModelsSettingsImpl { std::string layout; std::string mean; std::string scale; + std::string colorFormat; std::string modelVersionPolicy; uint32_t nireq = 0; std::string targetDevice; diff --git a/src/cli_parser.cpp b/src/cli_parser.cpp index cf0cf18f20..df9cbb60b0 100644 --- a/src/cli_parser.cpp +++ b/src/cli_parser.cpp @@ -267,6 +267,10 @@ std::variant> CLIParser::parse(int argc, char* "Resets model scale.", cxxopts::value(), "SCALE") + ("color_format", + "Resets model color format.", + cxxopts::value(), + "COLOR_FORMAT") ("model_version_policy", "Model version policy", cxxopts::value(), @@ -605,6 +609,11 @@ void CLIParser::prepareModel(ModelsSettingsImpl& modelsSettings, HFSettingsImpl& modelsSettings.userSetSingleModelArguments.push_back("scale"); } + if (result->count("color_format")) { + modelsSettings.colorFormat = result->operator[]("color_format").as(); + modelsSettings.userSetSingleModelArguments.push_back("color_format"); + } + if (result->count("model_version_policy")) { modelsSettings.modelVersionPolicy = result->operator[]("model_version_policy").as(); modelsSettings.userSetSingleModelArguments.push_back("model_version_policy"); diff --git a/src/config.cpp b/src/config.cpp index aea0675c37..e1b89fb1c3 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -379,6 +379,7 @@ const std::string& Config::Config::shape() const { return this->modelsSettings.s const std::string& Config::layout() const { return this->modelsSettings.layout; } const std::string& Config::means() const { return this->modelsSettings.mean; } const std::string& Config::scales() const { return this->modelsSettings.scale; } +const std::string& Config::colorFormat() const { return this->modelsSettings.colorFormat; } const std::string& Config::modelVersionPolicy() const { return this->modelsSettings.modelVersionPolicy; } uint32_t Config::nireq() const { return this->modelsSettings.nireq; } const std::string& Config::targetDevice() const { diff --git a/src/config.hpp b/src/config.hpp index fe7b3aec84..04756e463f 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -212,6 +212,13 @@ class Config { */ const std::string& scales() const; + /** + * @brief Get color format + * + * @return const std::string& + */ + const std::string& colorFormat() const; + /** * @brief Get the shape * diff --git a/src/modelconfig.cpp b/src/modelconfig.cpp index b600c4313a..e4af567014 100644 --- a/src/modelconfig.cpp +++ b/src/modelconfig.cpp @@ -432,7 +432,7 @@ Status ModelConfig::parseFloatArray(const std::string& str, std::vector& return StatusCode::OK; } -Status ModelConfig::parseFloatArrayOrValue(const std::string& str, float_map_or_value_t& values) { +Status ModelConfig::parseFloatArrayOrValue(const std::string& str, float_vec_or_value_t& values) { if (str.empty()) { return StatusCode::OK; } @@ -469,6 +469,38 @@ Status ModelConfig::parseScale(const std::string& command) { return parseFloatArrayOrValue(command, this->scaleValues); } +Status ModelConfig::parseColorFormat(const std::string& command) { + if (command.empty()) { + this->colorFormat = ov::preprocess::ColorFormat::RGB; + return StatusCode::OK; + } + + std::string upperCaseCommand; + std::transform(command.begin(), command.end(), std::back_inserter(upperCaseCommand), ::toupper); + + erase_spaces(upperCaseCommand); + + if (upperCaseCommand == "RGB") { + this->colorFormat = ov::preprocess::ColorFormat::RGB; + } else if (upperCaseCommand == "BGR") { + this->colorFormat = ov::preprocess::ColorFormat::BGR; + } else if (upperCaseCommand == "GRAY") { + this->colorFormat = ov::preprocess::ColorFormat::GRAY; + } else if (upperCaseCommand == "NV12") { + this->colorFormat = ov::preprocess::ColorFormat::NV12_SINGLE_PLANE; + } else if (upperCaseCommand == "NV12_2") { + this->colorFormat = ov::preprocess::ColorFormat::NV12_TWO_PLANES; + } else if (upperCaseCommand == "I420") { + this->colorFormat = ov::preprocess::ColorFormat::I420_SINGLE_PLANE; + } else if (upperCaseCommand == "I420_3") { + this->colorFormat = ov::preprocess::ColorFormat::I420_THREE_PLANES; + } else { + SPDLOG_WARN("Parameter contains invalid color format value: {}", command); + return StatusCode::COLOR_FORMAT_WRONG_FORMAT; + } + return StatusCode::OK; +} + Status ModelConfig::parseShape(ShapeInfo& shapeInfo, const std::string& str) { if (str == "auto") { SPDLOG_LOGGER_WARN(modelmanager_logger, "Shape auto is deprecated. Use model dynamic shapes instead. Check (https://docs.openvino.ai/2023.3/ovms_docs_dynamic_shape_dynamic_model.html#doxid-ovms-docs-dynamic-shape-dynamic-model)"); @@ -645,7 +677,14 @@ Status ModelConfig::parseNode(const rapidjson::Value& v) { } if (v.HasMember("scale")) { - Status status = this->parseMean(v["scale"].GetString()); + Status status = this->parseScale(v["scale"].GetString()); + if (!status.ok()) { + return status; + } + } + + if (v.HasMember("color_format")) { + Status status = this->parseColorFormat(v["color_format"].GetString()); if (!status.ok()) { return status; } diff --git a/src/modelconfig.hpp b/src/modelconfig.hpp index 069d9af2f1..aebeda7ead 100644 --- a/src/modelconfig.hpp +++ b/src/modelconfig.hpp @@ -42,7 +42,7 @@ class ModelVersionPolicy; using mapping_config_t = std::unordered_map; using plugin_config_t = std::map; using custom_loader_options_config_t = std::map; -using float_map_or_value_t = std::variant, float>; +using float_vec_or_value_t = std::variant, float>; extern const std::string MAPPING_CONFIG_JSON; const uint32_t DEFAULT_MAX_SEQUENCE_NUMBER = 500; @@ -205,13 +205,17 @@ class ModelConfig { /** * @brief meanValues mean preprocessing parameters */ - float_map_or_value_t meanValues; + float_vec_or_value_t meanValues; /** * @brief scaleValues scale preprocessing parameters */ - float_map_or_value_t scaleValues; + float_vec_or_value_t scaleValues; + /** + * @brief colorFormat color format preprocessing parameter + */ + ov::preprocess::ColorFormat colorFormat = ov::preprocess::ColorFormat::RGB; public: /** @@ -698,6 +702,16 @@ class ModelConfig { */ Status parseScale(const std::string& command); + /** + * @brief Parses value from string and extracts color format + * + * @param string + * + * @return status + */ + Status parseColorFormat(const std::string& command); + + /** * @brief Parses value from string and extracts float value * @@ -716,7 +730,7 @@ class ModelConfig { * * @return status */ - Status parseFloatArrayOrValue(const std::string& str, float_map_or_value_t& values); + Status parseFloatArrayOrValue(const std::string& str, float_vec_or_value_t& values); /** * @brief Parses value from string and extracts array of float values @@ -848,19 +862,33 @@ class ModelConfig { this->layout = LayoutConfiguration(); } - const float_map_or_value_t& getScales() const { + /** + * @brief Get the get scales + * + * @return const float_vec_or_value_t& + */ + const float_vec_or_value_t& getScales() const { return this->scaleValues; } /** * @brief Get the get means * - * @return const model_version_t& + * @return const float_vec_or_value_t& */ - const float_map_or_value_t& getMeans() const { + const float_vec_or_value_t& getMeans() const { return this->meanValues; } + /** + * @brief Get the get color format + * + * @return const ov::preprocess::ColorFormat& + */ + const ov::preprocess::ColorFormat& getColorFormat() const { + return this->colorFormat; + } + /** * @brief Get the version * diff --git a/src/modelinstance.cpp b/src/modelinstance.cpp index 65493866b7..caac04b1bb 100644 --- a/src/modelinstance.cpp +++ b/src/modelinstance.cpp @@ -232,18 +232,10 @@ const Layout ModelInstance::getReportedTensorLayout(const ModelConfig& config, c static Status applyPreprocessingConfiguration(ov::preprocess::PrePostProcessor& preproc, const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion) { OV_LOGGER("ov::preprocess::PrePostProcessor& preproc, const ModelConfig& config, std::shared_ptr& model"); - //resnet onnx model specific preprocessing - // std::vector scaleValues = { 58.395f, 57.12f, 57.375f }; - // std::vector meanValues = { 123.675f, 116.28f, 103.53f }; auto preprocessingScale = config.getScales(); auto preprocessingMean = config.getMeans(); - ov::preprocess::ColorFormat colorFormat = ov::preprocess::ColorFormat::RGB; // to be overridden by config - - auto debugPtr = std::get>(preprocessingMean); - for (const auto val : debugPtr) { - SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Using mean array value: {}", val); - } + ov::preprocess::ColorFormat colorFormat = config.getColorFormat(); preproc.input("data").tensor().set_color_format(colorFormat); diff --git a/src/modelmanager.cpp b/src/modelmanager.cpp index cd7d622ab8..991729b0e6 100644 --- a/src/modelmanager.cpp +++ b/src/modelmanager.cpp @@ -323,6 +323,12 @@ Status ModelManager::startFromConfig() { return status; } + status = modelConfig.parseColorFormat(config.colorFormat()); + if (!status.ok()) { + SPDLOG_LOGGER_ERROR(modelmanager_logger, "Couldn't parse color format parameter"); + return status; + } + bool batchSizeSet = (modelConfig.getBatchingMode() != FIXED || modelConfig.getBatchSize() != 0); bool shapeSet = (modelConfig.getShapes().size() > 0); diff --git a/src/status.hpp b/src/status.hpp index c82ca4b4b5..d058765d10 100644 --- a/src/status.hpp +++ b/src/status.hpp @@ -39,6 +39,7 @@ enum class StatusCode { SHAPE_WRONG_FORMAT, /*!< The provided shape param is in wrong format */ LAYOUT_WRONG_FORMAT, /*!< The provided layout param is in wrong format */ FLOAT_WRONG_FORMAT, /*!< The provided float param is in wrong format */ + COLOR_FORMAT_WRONG_FORMAT, /*!< The provided color format param is in wrong format */ DIM_WRONG_FORMAT, /*!< The provided dimension param is in wrong format */ PLUGIN_CONFIG_WRONG_FORMAT, /*!< Plugin config is in wrong format */ PLUGIN_CONFIG_CONFLICTING_PARAMETERS, /*!< Tried to set the same key twice in plugin config */ From fc98ba5b1d4249c2d0bdb512e9b3809886c33520 Mon Sep 17 00:00:00 2001 From: Pawel Date: Mon, 5 Jan 2026 11:20:52 +0100 Subject: [PATCH 06/16] layout update --- src/modelconfig.cpp | 5 +++++ src/modelinstance.cpp | 15 +++++++-------- src/modelinstance.hpp | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/modelconfig.cpp b/src/modelconfig.cpp index e4af567014..5225e1b536 100644 --- a/src/modelconfig.cpp +++ b/src/modelconfig.cpp @@ -170,21 +170,26 @@ bool ModelConfig::isBatchSizeConfigurationEqual(const ModelConfig& rhs) const { bool ModelConfig::isLayoutConfigurationEqual(const ModelConfig& rhs) const { if (this->layout != rhs.layout) { + SPDLOG_LOGGER_DEBUG(modelmanager_logger, "ModelConfig {} reload required due to layout mismatch", this->name); return false; } if (this->layouts.size() != rhs.layouts.size()) { + SPDLOG_LOGGER_DEBUG(modelmanager_logger, "ModelConfig {} reload required due to layout size mismatch", this->name); return false; } for (const auto& [name, layoutConfig] : this->layouts) { auto it = rhs.layouts.find(name); if (it == rhs.layouts.end()) { + SPDLOG_LOGGER_DEBUG(modelmanager_logger, "ModelConfig {} reload required due to layout name {} mismatch", this->name, name); return false; } if (layoutConfig != it->second) { + SPDLOG_LOGGER_DEBUG(modelmanager_logger, "ModelConfig {} reload required due to layout {} mismatch", this->name, name); return false; } } + SPDLOG_LOGGER_DEBUG(modelmanager_logger, "ModelConfig {} layout configuration match", this->name); return true; } diff --git a/src/modelinstance.cpp b/src/modelinstance.cpp index caac04b1bb..563605b132 100644 --- a/src/modelinstance.cpp +++ b/src/modelinstance.cpp @@ -467,7 +467,7 @@ Status ModelInstance::adjustForEmptyOutputNames() { return StatusCode::OK; } -Status ModelInstance::loadTensors(const ModelConfig& config, const DynamicModelParameter& parameter) { +Status ModelInstance::loadTensors(const ModelConfig& config, const bool hasLayoutConfigChanged, const DynamicModelParameter& parameter) { Status status = validateConfigurationAgainstNetwork(config, this->model); if (!status.ok()) { SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during configuration validation against model"); @@ -479,16 +479,15 @@ Status ModelInstance::loadTensors(const ModelConfig& config, const DynamicModelP return status; } - // bool hasLayoutConfigChanged = !config.isLayoutConfigurationEqual(this->config); - // bool needsToApplyLayoutConfiguration = hasLayoutConfigChanged || !this->model; + bool needsToApplyLayoutConfiguration = hasLayoutConfigChanged || !this->model; - // if (needsToApplyLayoutConfiguration) { + if (needsToApplyLayoutConfiguration) { status = applyPreprocessing(config, this->model, getName(), getVersion()); if (!status.ok()) { SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during layout/preprocessing configuration"); return status; } - // } + } status = loadInputTensors(config, parameter); if (!status.ok()) { SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during loading input tensors"); @@ -1004,7 +1003,7 @@ void ModelInstance::loadTensorFactories() { } Status ModelInstance::loadModelImpl(const ModelConfig& config, const DynamicModelParameter& parameter) { - bool isLayoutConfigurationChanged = !config.isLayoutConfigurationEqual(this->config); + bool hasLayoutConfigurationChanged = !config.isLayoutConfigurationEqual(this->config); subscriptionManager.notifySubscribers(); this->path = config.getPath(); @@ -1023,7 +1022,7 @@ Status ModelInstance::loadModelImpl(const ModelConfig& config, const DynamicMode return status; } - if (!this->model || isLayoutConfigurationChanged) { + if (!this->model || hasLayoutConfigurationChanged) { if (this->config.isCustomLoaderRequiredToLoadModel()) { status = loadOVModelUsingCustomLoader(); } else { @@ -1036,7 +1035,7 @@ Status ModelInstance::loadModelImpl(const ModelConfig& config, const DynamicMode return status; } - status = loadTensors(this->config, parameter); + status = loadTensors(this->config, hasLayoutConfigurationChanged, parameter); if (!status.ok()) { this->status.setLoading(ModelVersionStatusErrorCode::UNKNOWN); return status; diff --git a/src/modelinstance.hpp b/src/modelinstance.hpp index 9e9c9d3afe..6652e03190 100644 --- a/src/modelinstance.hpp +++ b/src/modelinstance.hpp @@ -306,7 +306,7 @@ class ModelInstance : public Servable { * * @param config */ - Status loadTensors(const ModelConfig& config, const DynamicModelParameter& parameter = DynamicModelParameter()); + Status loadTensors(const ModelConfig& config, const bool hasLayoutConfigChanged, const DynamicModelParameter& parameter = DynamicModelParameter()); /** * @brief Internal method for preprocessing model From 38c75ad5a9d2421850b3c7268056ebfa2cdcd036 Mon Sep 17 00:00:00 2001 From: Pawel Date: Mon, 5 Jan 2026 13:36:14 +0100 Subject: [PATCH 07/16] tests --- src/modelconfig.cpp | 8 ++++ src/test/modelconfig_test.cpp | 77 +++++++++++++++++++++++++++++++++++ src/test/ovmsconfig_test.cpp | 11 ++++- 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/modelconfig.cpp b/src/modelconfig.cpp index 5225e1b536..9b2862eead 100644 --- a/src/modelconfig.cpp +++ b/src/modelconfig.cpp @@ -434,6 +434,14 @@ Status ModelConfig::parseFloatArray(const std::string& str, std::vector& return status; } } + if (values.empty()) { + SPDLOG_WARN("Parameter contains empty float array: {}", str); + return StatusCode::FLOAT_WRONG_FORMAT; + } + if (values.size() < 2) { + SPDLOG_WARN("Parameter contains float array with less than 2 values: {}", str); + return StatusCode::FLOAT_WRONG_FORMAT; + } return StatusCode::OK; } diff --git a/src/test/modelconfig_test.cpp b/src/test/modelconfig_test.cpp index 3182c617ed..22ce7b5e96 100644 --- a/src/test/modelconfig_test.cpp +++ b/src/test/modelconfig_test.cpp @@ -196,6 +196,83 @@ TEST(ModelConfig, parseLayoutParam_multi) { } } +TEST(ModelConfig, parseMeanParameter) { + using namespace ovms; + ModelConfig config; + + std::string valid_str1 = "{123.675,116.28,103.53}"; + std::string valid_str2 = " { 0.0 , 255.0 ,128.5 } "; + std::string valid_str3 = "1.0"; + + ASSERT_EQ(config.parseMean(valid_str1), StatusCode::OK); + EXPECT_EQ(std::get>(config.getMeans()), (std::vector{123.675f, 116.28f, 103.53f})); + ASSERT_EQ(config.parseMean(valid_str2), StatusCode::OK); + EXPECT_EQ(std::get>(config.getMeans()), (std::vector{0.0f, 255.0f, 128.5f})); + ASSERT_EQ(config.parseMean(valid_str3), StatusCode::OK); + EXPECT_EQ(std::get(config.getMeans()), 1.0f); + + std::string invalid_str1 = "{123.675;116.28;103.53}"; + std::string invalid_str2 = "{123.675,abc,103.53}"; + std::string invalid_str3 = "one.point.zero"; + ASSERT_EQ(config.parseMean(invalid_str1), StatusCode::FLOAT_WRONG_FORMAT); + ASSERT_EQ(config.parseMean(invalid_str2), StatusCode::FLOAT_WRONG_FORMAT); + ASSERT_EQ(config.parseMean(invalid_str3), StatusCode::FLOAT_WRONG_FORMAT); +} + +TEST(ModelConfig, parseScaleParameter) { + using namespace ovms; + ModelConfig config; + + std::string valid_str1 = "{123.675,116.28,103.53}"; + std::string valid_str2 = " { 0.0 , 255.0 ,128.5 } "; + std::string valid_str3 = "1.0"; + + ASSERT_EQ(config.parseScale(valid_str1), StatusCode::OK); + EXPECT_EQ(std::get>(config.getScales()), (std::vector{123.675f, 116.28f, 103.53f})); + ASSERT_EQ(config.parseScale(valid_str2), StatusCode::OK); + EXPECT_EQ((std::get>(config.getScales())), (std::vector{0.0f, 255.0f, 128.5f})); + ASSERT_EQ(config.parseScale(valid_str3), StatusCode::OK); + EXPECT_EQ(std::get(config.getScales()), 1.0f); + std::string invalid_str1 = "{123.675;116.28;103.53}"; + std::string invalid_str2 = "{123.675,abc,103.53}"; + std::string invalid_str3 = "one.point.zero"; + ASSERT_EQ(config.parseScale(invalid_str1), StatusCode::FLOAT_WRONG_FORMAT); + ASSERT_EQ(config.parseScale(invalid_str2), StatusCode::FLOAT_WRONG_FORMAT); + ASSERT_EQ(config.parseScale(invalid_str3), StatusCode::FLOAT_WRONG_FORMAT); +} + +TEST(ModelConfig, parseColorFormatParameter) { + using namespace ovms; + ModelConfig config; + + std::string valid_str1 = "RGB"; + std::string valid_str2 = "BGR"; + std::string valid_str3 = "GRAY"; + std::string valid_str4 = "NV12"; + std::string valid_str5 = "NV12_2"; + std::string valid_str6 = "I420"; + std::string valid_str7 = "I420_3"; + + ASSERT_EQ(config.parseColorFormat(valid_str1), StatusCode::OK); + EXPECT_EQ(config.getColorFormat(), ov::preprocess::ColorFormat::RGB); + ASSERT_EQ(config.parseColorFormat(valid_str2), StatusCode::OK); + EXPECT_EQ(config.getColorFormat(), ov::preprocess::ColorFormat::BGR); + ASSERT_EQ(config.parseColorFormat(valid_str3), StatusCode::OK); + EXPECT_EQ(config.getColorFormat(), ov::preprocess::ColorFormat::GRAY); + ASSERT_EQ(config.parseColorFormat(valid_str4), StatusCode::OK); + EXPECT_EQ(config.getColorFormat(), ov::preprocess::ColorFormat::NV12_SINGLE_PLANE); + ASSERT_EQ(config.parseColorFormat(valid_str5), StatusCode::OK); + EXPECT_EQ(config.getColorFormat(), ov::preprocess::ColorFormat::NV12_TWO_PLANES); + ASSERT_EQ(config.parseColorFormat(valid_str6), StatusCode::OK); + EXPECT_EQ(config.getColorFormat(), ov::preprocess::ColorFormat::I420_SINGLE_PLANE); + ASSERT_EQ(config.parseColorFormat(valid_str7), StatusCode::OK); + EXPECT_EQ(config.getColorFormat(), ov::preprocess::ColorFormat::I420_THREE_PLANES); + + std::string invalid_str1 = "INVALID_FORMAT"; + auto status = config.parseColorFormat(invalid_str1); + EXPECT_EQ(status, ovms::StatusCode::COLOR_FORMAT_WRONG_FORMAT); +} + TEST(ModelConfig, shape) { ovms::ModelConfig config; diff --git a/src/test/ovmsconfig_test.cpp b/src/test/ovmsconfig_test.cpp index ade6f80db3..2c5c35ecc8 100644 --- a/src/test/ovmsconfig_test.cpp +++ b/src/test/ovmsconfig_test.cpp @@ -2432,6 +2432,12 @@ TEST(OvmsConfigTest, positiveSingle) { "(3:5,5:6)", "--layout", "nchw:nhwc", + "--mean", + "{123.675,116.28,103.53}", + "--scale", + "{58.395,57.12,57.375}", + "--color_format", + "BGR", "--model_version_policy", "setting", "--nireq", @@ -2449,7 +2455,7 @@ TEST(OvmsConfigTest, positiveSingle) { "--max_sequence_number", "52", }; - int arg_count = 55; + int arg_count = 61; ConstructorEnabledConfig config; config.parse(arg_count, n_argv); @@ -2477,6 +2483,9 @@ TEST(OvmsConfigTest, positiveSingle) { EXPECT_EQ(config.batchSize(), "(3:5)"); EXPECT_EQ(config.shape(), "(3:5,5:6)"); EXPECT_EQ(config.layout(), "nchw:nhwc"); + EXPECT_EQ(config.means(), "{123.675,116.28,103.53}"); + EXPECT_EQ(config.scales(), "{58.395,57.12,57.375}"); + EXPECT_EQ(config.colorFormat(), "BGR"); EXPECT_EQ(config.modelVersionPolicy(), "setting"); EXPECT_EQ(config.nireq(), 2); EXPECT_EQ(config.targetDevice(), "GPU"); From e0cb428b39eee493fd8e895fc98a97698cf1342a Mon Sep 17 00:00:00 2001 From: Pawel Date: Wed, 7 Jan 2026 08:41:14 +0100 Subject: [PATCH 08/16] general input instead of named --- src/modelconfig.hpp | 4 ++-- src/modelinstance.cpp | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/modelconfig.hpp b/src/modelconfig.hpp index aebeda7ead..69d7534c92 100644 --- a/src/modelconfig.hpp +++ b/src/modelconfig.hpp @@ -205,12 +205,12 @@ class ModelConfig { /** * @brief meanValues mean preprocessing parameters */ - float_vec_or_value_t meanValues; + float_vec_or_value_t meanValues = 0.0f; /** * @brief scaleValues scale preprocessing parameters */ - float_vec_or_value_t scaleValues; + float_vec_or_value_t scaleValues = 1.0f; /** * @brief colorFormat color format preprocessing parameter diff --git a/src/modelinstance.cpp b/src/modelinstance.cpp index 563605b132..671d832f50 100644 --- a/src/modelinstance.cpp +++ b/src/modelinstance.cpp @@ -237,12 +237,20 @@ static Status applyPreprocessingConfiguration(ov::preprocess::PrePostProcessor& auto preprocessingMean = config.getMeans(); ov::preprocess::ColorFormat colorFormat = config.getColorFormat(); - preproc.input("data").tensor().set_color_format(colorFormat); + preproc.input().tensor().set_color_format(colorFormat); + preproc.input().preprocess().convert_color(colorFormat); - preproc.input("data").preprocess() - .mean(std::get>(preprocessingMean)) - .scale(std::get>(preprocessingScale)) - .convert_color(colorFormat); + if (auto* mean = std::get_if(&preprocessingMean)) { + preproc.input().preprocess().mean(*mean); + } else { + preproc.input().preprocess().mean(std::get>(preprocessingMean)); + } + + if (auto* scale = std::get_if(&preprocessingScale)) { + preproc.input().preprocess().scale(*scale); + } else { + preproc.input().preprocess().scale(std::get>(preprocessingScale)); + } return StatusCode::OK; } @@ -377,7 +385,6 @@ Status ModelInstance::applyPreprocessing(const ModelConfig& config, std::shared_ ov::preprocess::PrePostProcessor preproc(model); Status status = StatusCode::OK; - SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Applying layout configuration"); status = applyLayoutConfiguration(preproc, config, model, modelName, modelVersion); if (!status.ok()) { From be001b14a9a56808138d4c62eb51bc354d3f1083 Mon Sep 17 00:00:00 2001 From: Pawel Date: Wed, 7 Jan 2026 09:00:16 +0100 Subject: [PATCH 09/16] refactor --- src/modelinstance.cpp | 55 +++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/src/modelinstance.cpp b/src/modelinstance.cpp index 671d832f50..1e358bac52 100644 --- a/src/modelinstance.cpp +++ b/src/modelinstance.cpp @@ -230,28 +230,47 @@ const Layout ModelInstance::getReportedTensorLayout(const ModelConfig& config, c return defaultLayout; } -static Status applyPreprocessingConfiguration(ov::preprocess::PrePostProcessor& preproc, const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion) { - OV_LOGGER("ov::preprocess::PrePostProcessor& preproc, const ModelConfig& config, std::shared_ptr& model"); - - auto preprocessingScale = config.getScales(); - auto preprocessingMean = config.getMeans(); - ov::preprocess::ColorFormat colorFormat = config.getColorFormat(); - - preproc.input().tensor().set_color_format(colorFormat); - preproc.input().preprocess().convert_color(colorFormat); - - if (auto* mean = std::get_if(&preprocessingMean)) { - preproc.input().preprocess().mean(*mean); +static void applyPreprocessingConfiguration(ov::preprocess::PrePostProcessor& preproc, ov::float_vec_or_value_t config, bool isScale) { + if (auto* scalar = std::get_if(&config)) { + isScale ? preproc.input().preprocess().scale(*scalar) : preproc.input().preprocess().mean(*scalar); } else { - preproc.input().preprocess().mean(std::get>(preprocessingMean)); + isScale ? preproc.input().preprocess().scale(std::get>(config)) : preproc.input().preprocess().mean(std::get>(config)); } +} - if (auto* scale = std::get_if(&preprocessingScale)) { - preproc.input().preprocess().scale(*scale); - } else { - preproc.input().preprocess().scale(std::get>(preprocessingScale)); +static Status applyPreprocessingConfiguration(ov::preprocess::PrePostProcessor& preproc, const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion) { + OV_LOGGER("ov::preprocess::PrePostProcessor& preproc, const ModelConfig& config, std::shared_ptr& model"); + + try { + auto preprocessingScale = config.getScales(); + auto preprocessingMean = config.getMeans(); + ov::preprocess::ColorFormat colorFormat = config.getColorFormat(); + + preproc.input().tensor().set_color_format(colorFormat); + preproc.input().preprocess().convert_color(colorFormat); + + applyPreprocessingConfiguration(preproc, preprocessingMean, false); + applyPreprocessingConfiguration(preproc, preprocessingScale, true); + + } catch (const ov::Exception& e) { + SPDLOG_LOGGER_ERROR(modelmanager_logger, "Failed to configure input preprocessing configuration for model:{}; version:{}; from OpenVINO with error:{}", + modelName, + modelVersion, + e.what()); + return StatusCode::UNKNOWN_ERROR; + } catch (const std::exception& e) { + SPDLOG_LOGGER_ERROR(modelmanager_logger, "Failed to configure input preprocessing configuration for model:{}; version:{}; from OpenVINO with error:{}", + modelName, + modelVersion, + e.what()); + return StatusCode::UNKNOWN_ERROR; + } catch (...) { + SPDLOG_LOGGER_ERROR(modelmanager_logger, "Failed to configure input preprocessing configuration for model:{}; version:{}; from OpenVINO", + modelName, + modelVersion); + return StatusCode::UNKNOWN_ERROR; } - + return StatusCode::OK; } From 74606d6bbdc659dd7f909cf5bb46a07158a81cdc Mon Sep 17 00:00:00 2001 From: Pawel Date: Wed, 7 Jan 2026 09:11:38 +0100 Subject: [PATCH 10/16] fix --- src/modelinstance.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/modelinstance.cpp b/src/modelinstance.cpp index 1e358bac52..0b1a85582b 100644 --- a/src/modelinstance.cpp +++ b/src/modelinstance.cpp @@ -230,7 +230,7 @@ const Layout ModelInstance::getReportedTensorLayout(const ModelConfig& config, c return defaultLayout; } -static void applyPreprocessingConfiguration(ov::preprocess::PrePostProcessor& preproc, ov::float_vec_or_value_t config, bool isScale) { +static void applyScaleOrMeanPreprocessing(ov::preprocess::PrePostProcessor& preproc, ovms::float_vec_or_value_t& config, bool isScale) { if (auto* scalar = std::get_if(&config)) { isScale ? preproc.input().preprocess().scale(*scalar) : preproc.input().preprocess().mean(*scalar); } else { @@ -242,15 +242,18 @@ static Status applyPreprocessingConfiguration(ov::preprocess::PrePostProcessor& OV_LOGGER("ov::preprocess::PrePostProcessor& preproc, const ModelConfig& config, std::shared_ptr& model"); try { - auto preprocessingScale = config.getScales(); - auto preprocessingMean = config.getMeans(); + ovms::float_vec_or_value_t preprocessingScale = config.getScales(); + ovms::float_vec_or_value_t preprocessingMean = config.getMeans(); ov::preprocess::ColorFormat colorFormat = config.getColorFormat(); + OV_LOGGER("Applying color format for model: {}, version: {}", modelName, modelVersion); preproc.input().tensor().set_color_format(colorFormat); preproc.input().preprocess().convert_color(colorFormat); - applyPreprocessingConfiguration(preproc, preprocessingMean, false); - applyPreprocessingConfiguration(preproc, preprocessingScale, true); + OV_LOGGER("Applying mean configuration: {} for model: {}, version: {}", modelName, modelVersion); + applyScaleOrMeanPreprocessing(preproc, preprocessingMean, false); + OV_LOGGER("Applying scale configuration: {} for model: {}, version: {}", modelName, modelVersion); + applyScaleOrMeanPreprocessing(preproc, preprocessingScale, true); } catch (const ov::Exception& e) { SPDLOG_LOGGER_ERROR(modelmanager_logger, "Failed to configure input preprocessing configuration for model:{}; version:{}; from OpenVINO with error:{}", @@ -270,7 +273,7 @@ static Status applyPreprocessingConfiguration(ov::preprocess::PrePostProcessor& modelVersion); return StatusCode::UNKNOWN_ERROR; } - + return StatusCode::OK; } From 14452b233eb959953838582bb30383a71ebe7337 Mon Sep 17 00:00:00 2001 From: Pawel Date: Wed, 7 Jan 2026 09:39:19 +0100 Subject: [PATCH 11/16] remove debug logs --- src/modelconfig.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/modelconfig.cpp b/src/modelconfig.cpp index 9b2862eead..21bb9c490e 100644 --- a/src/modelconfig.cpp +++ b/src/modelconfig.cpp @@ -170,26 +170,21 @@ bool ModelConfig::isBatchSizeConfigurationEqual(const ModelConfig& rhs) const { bool ModelConfig::isLayoutConfigurationEqual(const ModelConfig& rhs) const { if (this->layout != rhs.layout) { - SPDLOG_LOGGER_DEBUG(modelmanager_logger, "ModelConfig {} reload required due to layout mismatch", this->name); return false; } if (this->layouts.size() != rhs.layouts.size()) { - SPDLOG_LOGGER_DEBUG(modelmanager_logger, "ModelConfig {} reload required due to layout size mismatch", this->name); return false; } for (const auto& [name, layoutConfig] : this->layouts) { auto it = rhs.layouts.find(name); if (it == rhs.layouts.end()) { - SPDLOG_LOGGER_DEBUG(modelmanager_logger, "ModelConfig {} reload required due to layout name {} mismatch", this->name, name); return false; } if (layoutConfig != it->second) { - SPDLOG_LOGGER_DEBUG(modelmanager_logger, "ModelConfig {} reload required due to layout {} mismatch", this->name, name); return false; } } - SPDLOG_LOGGER_DEBUG(modelmanager_logger, "ModelConfig {} layout configuration match", this->name); return true; } From f3a411c347ce92409a714d08233a80c6455b5d98 Mon Sep 17 00:00:00 2001 From: Pawel Date: Thu, 8 Jan 2026 10:53:55 +0100 Subject: [PATCH 12/16] save --- demos/using_onnx_model/python/Makefile | 39 --- demos/using_onnx_model/python/README.md | 40 +-- demos/using_onnx_model/python/config.json | 72 ----- .../python/onnx_model_demo.py | 4 +- demos/using_onnx_model/venv/bin/Activate.ps1 | 247 ++++++++++++++++++ demos/using_onnx_model/venv/bin/activate | 69 +++++ demos/using_onnx_model/venv/bin/activate.csh | 26 ++ demos/using_onnx_model/venv/bin/activate.fish | 69 +++++ demos/using_onnx_model/venv/bin/f2py | 8 + demos/using_onnx_model/venv/bin/normalizer | 8 + demos/using_onnx_model/venv/bin/pip | 8 + demos/using_onnx_model/venv/bin/pip3 | 8 + demos/using_onnx_model/venv/bin/pip3.10 | 8 + demos/using_onnx_model/venv/bin/python | 1 + demos/using_onnx_model/venv/bin/python3 | 1 + demos/using_onnx_model/venv/bin/python3.10 | 1 + demos/using_onnx_model/venv/lib64 | 1 + demos/using_onnx_model/venv/pyvenv.cfg | 3 + src/modelconfig.cpp | 10 +- src/test/modelconfig_test.cpp | 31 ++- src/test/ovmsconfig_test.cpp | 8 +- 21 files changed, 501 insertions(+), 161 deletions(-) delete mode 100644 demos/using_onnx_model/python/Makefile delete mode 100644 demos/using_onnx_model/python/config.json create mode 100644 demos/using_onnx_model/venv/bin/Activate.ps1 create mode 100644 demos/using_onnx_model/venv/bin/activate create mode 100644 demos/using_onnx_model/venv/bin/activate.csh create mode 100644 demos/using_onnx_model/venv/bin/activate.fish create mode 100755 demos/using_onnx_model/venv/bin/f2py create mode 100755 demos/using_onnx_model/venv/bin/normalizer create mode 100755 demos/using_onnx_model/venv/bin/pip create mode 100755 demos/using_onnx_model/venv/bin/pip3 create mode 100755 demos/using_onnx_model/venv/bin/pip3.10 create mode 120000 demos/using_onnx_model/venv/bin/python create mode 120000 demos/using_onnx_model/venv/bin/python3 create mode 120000 demos/using_onnx_model/venv/bin/python3.10 create mode 120000 demos/using_onnx_model/venv/lib64 create mode 100644 demos/using_onnx_model/venv/pyvenv.cfg diff --git a/demos/using_onnx_model/python/Makefile b/demos/using_onnx_model/python/Makefile deleted file mode 100644 index 6deda2910b..0000000000 --- a/demos/using_onnx_model/python/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright (c) 2022 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -.PHONY: client_preprocessing, server_preprocessing - -default: client_preprocessing - -client_preprocessing: -# Download ONNX ResNet50 model - curl --fail -L --create-dirs https://github.com/onnx/models/raw/main/validated/vision/classification/resnet/model/resnet50-caffe2-v1-9.onnx -o workspace/resnet50-onnx/1/resnet50-caffe2-v1-9.onnx - -BASE_OS?=ubuntu - -server_preprocessing: -# Download ONNX ResNet50 model - curl --fail -L --create-dirs https://github.com/onnx/models/raw/main/validated/vision/classification/resnet/model/resnet50-caffe2-v1-9.onnx -o workspace/resnet50-onnx/1/resnet50-caffe2-v1-9.onnx -# Build custom node - cd ../../../src/custom_nodes && \ - make BASE_OS=${BASE_OS} NODES=image_transformation && \ - mkdir -p ../../demos/using_onnx_model/python/workspace/lib && \ - mv lib/${BASE_OS}/libcustom_node_image_transformation.so ../../demos/using_onnx_model/python/workspace/lib/libcustom_node_image_transformation.so -# Copy configuration file to workspace directory - cp config.json workspace/. - -clean: - @rm -rf workspace diff --git a/demos/using_onnx_model/python/README.md b/demos/using_onnx_model/python/README.md index 26b82d0d82..779a65a1b3 100644 --- a/demos/using_onnx_model/python/README.md +++ b/demos/using_onnx_model/python/README.md @@ -4,7 +4,7 @@ Steps are similar to when you work with IR model format. Model Server accepts ON Below is a complete functional use case using Python 3.7 or higher. For this example let's use a public [ONNX ResNet](https://github.com/onnx/models/tree/main/validated/vision/classification/resnet) model - resnet50-caffe2-v1-9.onnx model. -This model requires additional [preprocessing function](https://github.com/onnx/models/tree/main/validated/vision/classification/resnet#preprocessing). Preprocessing can be performed in the client by manipulating data before sending the request. Preprocessing can be also delegated to the server by creating a [DAG](../../../docs/dag_scheduler.md) and using a custom processing node. Both methods will be explained below. +This model requires additional [preprocessing function](https://github.com/onnx/models/tree/main/validated/vision/classification/resnet#preprocessing). Preprocessing can be performed in the client by manipulating data before sending the request. Preprocessing can be also delegated to the server by setting preprocessing parameters. Both methods will be explained below. [Option 1: Adding preprocessing to the client side](#option-1-adding-preprocessing-to-the-client-side) [Option 2: Adding preprocessing to the server side (building DAG)](#option-2-adding-preprocessing-to-the-server-side-building-a-dag) @@ -17,9 +17,9 @@ git clone https://github.com/openvinotoolkit/model_server.git cd model_server/demos/using_onnx_model/python ``` -Prepare workspace with the model by running: +Download classification model ```bash -make client_preprocessing +curl --fail -L --create-dirs https://github.com/onnx/models/raw/main/validated/vision/classification/resnet/model/resnet50-caffe2-v1-9.onnx -o workspace/resnet50-onnx/1/resnet50-caffe2-v1-9.onnx ``` You should see `workspace` directory created with the following content: @@ -55,29 +55,13 @@ Detected class name: bee ## Option 2: Adding preprocessing to the server side (building a DAG) -Prepare workspace with the model, preprocessing node library and configuration file by running: -```bash -make server_preprocessing -``` - -You should see `workspace` directory created with the following content: -```bash -workspace/ -├── config.json -├── lib -│   └── libcustom_node_image_transformation.so -└── resnet50-onnx - └── 1 - └── resnet50-caffe2-v1-9.onnx -``` - -Start the OVMS container with a configuration file option: +Start the OVMS container with additional preprocessing options: ```bash docker run -d -u $(id -u):$(id -g) -v $(pwd)/workspace:/workspace -p 9001:9001 openvino/model_server:latest \ ---config_path /workspace/config.json --port 9001 +--model_path /workspace/resnet50-onnx --model_name resnet --port 9001 --layout NHWC:NCHW --mean "[123.675,116.28,103.53]" --scale "[58.395,57.12,57.375]" --shape "(1,224,224,3)" --color_format BGR ``` -The `onnx_model_demo.py` script can run inference both with and without performing preprocessing. Since in this variant preprocessing is done by the model server (via custom node), there's no need to perform any image preprocessing on the client side. In that case, run without `--run_preprocessing` option. See [preprocessing function](https://github.com/openvinotoolkit/model_server/blob/main/demos/using_onnx_model/python/onnx_model_demo.py#L26-L33) run in the client. +The `onnx_model_demo.py` script can run inference both with and without performing preprocessing. Since in this variant preprocessing is done by the model server, there's no need to perform any image preprocessing on the client side. In that case, run without `--run_preprocessing` option. See [preprocessing function](https://github.com/openvinotoolkit/model_server/blob/main/demos/using_onnx_model/python/onnx_model_demo.py#L26-L33) run in the client. Run the client without preprocessing: ```bash @@ -86,15 +70,3 @@ Running without preprocessing on client side Class is with highest score: 309 Detected class name: bee ``` - -## Node parameters explanation -Additional preprocessing step applies a division and an subtraction to each pixel value in the image. This calculation is configured by passing two parameters to _image transformation_ custom node in [config.json](https://github.com/openvinotoolkit/model_server/blob/main/demos/using_onnx_model/python/config.json#L32-L33): -``` -"params": { - ... - "mean_values": "[123.675,116.28,103.53]", - "scale_values": "[58.395,57.12,57.375]", - ... -} -``` -For each pixel, the custom node subtracted `123.675` from blue value, `116.28` from green value and `103.53` from red value. Next, it divides in the same color order using `58.395`, `57.12`, `57.375` values. This way we match the image data to the input required by onnx model. diff --git a/demos/using_onnx_model/python/config.json b/demos/using_onnx_model/python/config.json deleted file mode 100644 index c25117b762..0000000000 --- a/demos/using_onnx_model/python/config.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "model_config_list": [ - { - "config": { - "name": "resnet_model", - "base_path": "/workspace/resnet50-onnx", - "layout": "NHWC:NCHW", - "shape": "(1,224,224,3)", - "plugin_config": { - "NUM_STREAMS": "1" - } - } - } - ], - "custom_node_library_config_list": [ - {"name": "image_transformation", - "base_path": "/workspace/lib/libcustom_node_image_transformation.so"} - ], - "pipeline_config_list": [ - { - "name": "resnet", - "inputs": ["0"], - "nodes": [ - { - "name": "image_transformation_node", - "library_name": "image_transformation", - "type": "custom", - "params": { - "target_image_width": "224", - "target_image_height": "224", - - "mean_values": "[123.675,116.28,103.53]", - "scale_values": "[58.395,57.12,57.375]", - - "original_image_color_order": "BGR", - "target_image_color_order": "BGR", - - "original_image_layout": "NHWC", - "target_image_layout": "NHWC", - - "debug": "true" - }, - "inputs": [ - {"image": { - "node_name": "request", - "data_item": "0"}}], - "outputs": [ - {"data_item": "image", - "alias": "transformed_image"}] - }, - { - "name": "resnet_node", - "model_name": "resnet_model", - "type": "DL model", - "inputs": [ - {"gpu_0/data_0": {"node_name": "image_transformation_node", - "data_item": "transformed_image"}} - ], - "outputs": [ - {"data_item": "gpu_0/softmax_1", - "alias": "1463"} - ] - } - ], - "outputs": [ - {"1463": { - "node_name": "resnet_node", - "data_item": "1463"}} - ] - } - ] -} diff --git a/demos/using_onnx_model/python/onnx_model_demo.py b/demos/using_onnx_model/python/onnx_model_demo.py index d53831819d..c3c981debe 100644 --- a/demos/using_onnx_model/python/onnx_model_demo.py +++ b/demos/using_onnx_model/python/onnx_model_demo.py @@ -60,12 +60,12 @@ def getJpeg(path, size): if args["run_preprocessing"]: print("Running with preprocessing on client side") img = getJpeg(args["image_path"], 224) - input_name = "gpu_0/data_0" + input_name = "data" else: print("Running without preprocessing on client side") with open(args["image_path"], "rb") as f: img = f.read() - input_name = "0" + input_name = "data" client = make_grpc_client(args["service_url"]) output = client.predict({input_name: img}, "resnet") diff --git a/demos/using_onnx_model/venv/bin/Activate.ps1 b/demos/using_onnx_model/venv/bin/Activate.ps1 new file mode 100644 index 0000000000..b49d77ba44 --- /dev/null +++ b/demos/using_onnx_model/venv/bin/Activate.ps1 @@ -0,0 +1,247 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/demos/using_onnx_model/venv/bin/activate b/demos/using_onnx_model/venv/bin/activate new file mode 100644 index 0000000000..38e73213ca --- /dev/null +++ b/demos/using_onnx_model/venv/bin/activate @@ -0,0 +1,69 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV=/opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/"bin":$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1='(venv) '"${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT='(venv) ' + export VIRTUAL_ENV_PROMPT +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null +fi diff --git a/demos/using_onnx_model/venv/bin/activate.csh b/demos/using_onnx_model/venv/bin/activate.csh new file mode 100644 index 0000000000..773558a25b --- /dev/null +++ b/demos/using_onnx_model/venv/bin/activate.csh @@ -0,0 +1,26 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV /opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/"bin":$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = '(venv) '"$prompt" + setenv VIRTUAL_ENV_PROMPT '(venv) ' +endif + +alias pydoc python -m pydoc + +rehash diff --git a/demos/using_onnx_model/venv/bin/activate.fish b/demos/using_onnx_model/venv/bin/activate.fish new file mode 100644 index 0000000000..6d8b558ab1 --- /dev/null +++ b/demos/using_onnx_model/venv/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/); you cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV /opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/"bin $PATH + +# Unset PYTHONHOME if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # Save the current fish_prompt function as the function _old_fish_prompt. + functions -c fish_prompt _old_fish_prompt + + # With the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command. + set -l old_status $status + + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) '(venv) ' (set_color normal) + + # Restore the return status of the previous command. + echo "exit $old_status" | . + # Output the original/"old" prompt. + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + set -gx VIRTUAL_ENV_PROMPT '(venv) ' +end diff --git a/demos/using_onnx_model/venv/bin/f2py b/demos/using_onnx_model/venv/bin/f2py new file mode 100755 index 0000000000..096d479fe0 --- /dev/null +++ b/demos/using_onnx_model/venv/bin/f2py @@ -0,0 +1,8 @@ +#!/opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from numpy.f2py.f2py2e import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/demos/using_onnx_model/venv/bin/normalizer b/demos/using_onnx_model/venv/bin/normalizer new file mode 100755 index 0000000000..e77a52dc9e --- /dev/null +++ b/demos/using_onnx_model/venv/bin/normalizer @@ -0,0 +1,8 @@ +#!/opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from charset_normalizer.cli import cli_detect +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(cli_detect()) diff --git a/demos/using_onnx_model/venv/bin/pip b/demos/using_onnx_model/venv/bin/pip new file mode 100755 index 0000000000..0fe5b4850e --- /dev/null +++ b/demos/using_onnx_model/venv/bin/pip @@ -0,0 +1,8 @@ +#!/opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/demos/using_onnx_model/venv/bin/pip3 b/demos/using_onnx_model/venv/bin/pip3 new file mode 100755 index 0000000000..0fe5b4850e --- /dev/null +++ b/demos/using_onnx_model/venv/bin/pip3 @@ -0,0 +1,8 @@ +#!/opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/demos/using_onnx_model/venv/bin/pip3.10 b/demos/using_onnx_model/venv/bin/pip3.10 new file mode 100755 index 0000000000..0fe5b4850e --- /dev/null +++ b/demos/using_onnx_model/venv/bin/pip3.10 @@ -0,0 +1,8 @@ +#!/opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/demos/using_onnx_model/venv/bin/python b/demos/using_onnx_model/venv/bin/python new file mode 120000 index 0000000000..b8a0adbbb9 --- /dev/null +++ b/demos/using_onnx_model/venv/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/demos/using_onnx_model/venv/bin/python3 b/demos/using_onnx_model/venv/bin/python3 new file mode 120000 index 0000000000..79ab74b1e1 --- /dev/null +++ b/demos/using_onnx_model/venv/bin/python3 @@ -0,0 +1 @@ +/usr/local/bin/python3 \ No newline at end of file diff --git a/demos/using_onnx_model/venv/bin/python3.10 b/demos/using_onnx_model/venv/bin/python3.10 new file mode 120000 index 0000000000..b8a0adbbb9 --- /dev/null +++ b/demos/using_onnx_model/venv/bin/python3.10 @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/demos/using_onnx_model/venv/lib64 b/demos/using_onnx_model/venv/lib64 new file mode 120000 index 0000000000..7951405f85 --- /dev/null +++ b/demos/using_onnx_model/venv/lib64 @@ -0,0 +1 @@ +lib \ No newline at end of file diff --git a/demos/using_onnx_model/venv/pyvenv.cfg b/demos/using_onnx_model/venv/pyvenv.cfg new file mode 100644 index 0000000000..7a355ea6b0 --- /dev/null +++ b/demos/using_onnx_model/venv/pyvenv.cfg @@ -0,0 +1,3 @@ +home = /usr/local/bin +include-system-site-packages = false +version = 3.10.12 diff --git a/src/modelconfig.cpp b/src/modelconfig.cpp index 21bb9c490e..375f8922ea 100644 --- a/src/modelconfig.cpp +++ b/src/modelconfig.cpp @@ -407,7 +407,12 @@ Status ModelConfig::parseLayoutParameter(const std::string& command) { Status ModelConfig::parseFloat(const std::string& str, float& value) { try { - value = std::stof(str); + size_t processCount = 0; + value = std::stof(str, &processCount); + if (processCount != str.size()) { + SPDLOG_WARN("Parameter contains invalid float value: {}", str); + return StatusCode::FLOAT_WRONG_FORMAT; + } } catch (const std::invalid_argument&) { SPDLOG_WARN("Parameter contains invalid float value: {}", str); return StatusCode::FLOAT_WRONG_FORMAT; @@ -450,7 +455,8 @@ Status ModelConfig::parseFloatArrayOrValue(const std::string& str, float_vec_or_ erase_spaces(upperCaseCommand); - if (*upperCaseCommand.begin() == '{' && *upperCaseCommand.rbegin() == '}') { + if ((*upperCaseCommand.begin() == '[' && *upperCaseCommand.rbegin() == ']') || + (*upperCaseCommand.begin() == '(' && *upperCaseCommand.rbegin() == ')')) { auto commandWithoutBraces = upperCaseCommand.substr(1, upperCaseCommand.size() - 2); std::vector vals; auto status = parseFloatArray(commandWithoutBraces, vals); diff --git a/src/test/modelconfig_test.cpp b/src/test/modelconfig_test.cpp index 22ce7b5e96..eca7d8567e 100644 --- a/src/test/modelconfig_test.cpp +++ b/src/test/modelconfig_test.cpp @@ -200,9 +200,10 @@ TEST(ModelConfig, parseMeanParameter) { using namespace ovms; ModelConfig config; - std::string valid_str1 = "{123.675,116.28,103.53}"; - std::string valid_str2 = " { 0.0 , 255.0 ,128.5 } "; + std::string valid_str1 = "[123.675,116.28,103.53]"; + std::string valid_str2 = " [ 0.0 , 255.0 ,128.5 ] "; std::string valid_str3 = "1.0"; + std::string valid_str4 = "(123.675,116.28,103.53)"; ASSERT_EQ(config.parseMean(valid_str1), StatusCode::OK); EXPECT_EQ(std::get>(config.getMeans()), (std::vector{123.675f, 116.28f, 103.53f})); @@ -210,22 +211,29 @@ TEST(ModelConfig, parseMeanParameter) { EXPECT_EQ(std::get>(config.getMeans()), (std::vector{0.0f, 255.0f, 128.5f})); ASSERT_EQ(config.parseMean(valid_str3), StatusCode::OK); EXPECT_EQ(std::get(config.getMeans()), 1.0f); + ASSERT_EQ(config.parseMean(valid_str4), StatusCode::OK); + EXPECT_EQ(std::get>(config.getMeans()), (std::vector{123.675f, 116.28f, 103.53f})); - std::string invalid_str1 = "{123.675;116.28;103.53}"; - std::string invalid_str2 = "{123.675,abc,103.53}"; + std::string invalid_str1 = "[123.675;116.28;103.53]"; + std::string invalid_str2 = "[123.675,abc,103.53]"; std::string invalid_str3 = "one.point.zero"; + std::string invalid_str4 = "{123.675,116.28,103.53}"; + std::string invalid_str5 = "123.675,116.28,103.53"; ASSERT_EQ(config.parseMean(invalid_str1), StatusCode::FLOAT_WRONG_FORMAT); ASSERT_EQ(config.parseMean(invalid_str2), StatusCode::FLOAT_WRONG_FORMAT); ASSERT_EQ(config.parseMean(invalid_str3), StatusCode::FLOAT_WRONG_FORMAT); + ASSERT_EQ(config.parseMean(invalid_str4), StatusCode::FLOAT_WRONG_FORMAT); + ASSERT_EQ(config.parseMean(invalid_str5), StatusCode::FLOAT_WRONG_FORMAT); } TEST(ModelConfig, parseScaleParameter) { using namespace ovms; ModelConfig config; - std::string valid_str1 = "{123.675,116.28,103.53}"; - std::string valid_str2 = " { 0.0 , 255.0 ,128.5 } "; + std::string valid_str1 = "[123.675,116.28,103.53]"; + std::string valid_str2 = " [ 0.0 , 255.0 ,128.5 ] "; std::string valid_str3 = "1.0"; + std::string valid_str4 = "(123.675,116.28,103.53)"; ASSERT_EQ(config.parseScale(valid_str1), StatusCode::OK); EXPECT_EQ(std::get>(config.getScales()), (std::vector{123.675f, 116.28f, 103.53f})); @@ -233,12 +241,19 @@ TEST(ModelConfig, parseScaleParameter) { EXPECT_EQ((std::get>(config.getScales())), (std::vector{0.0f, 255.0f, 128.5f})); ASSERT_EQ(config.parseScale(valid_str3), StatusCode::OK); EXPECT_EQ(std::get(config.getScales()), 1.0f); - std::string invalid_str1 = "{123.675;116.28;103.53}"; - std::string invalid_str2 = "{123.675,abc,103.53}"; + ASSERT_EQ(config.parseScale(valid_str4), StatusCode::OK); + EXPECT_EQ(std::get>(config.getScales()), (std::vector{123.675f, 116.28f, 103.53f})); + + std::string invalid_str1 = "[123.675;116.28;103.53]"; + std::string invalid_str2 = "[123.675,abc,103.53]"; std::string invalid_str3 = "one.point.zero"; + std::string invalid_str4 = "{123.675,116.28,103.53}"; + std::string invalid_str5 = "123.675,116.28,103.53"; ASSERT_EQ(config.parseScale(invalid_str1), StatusCode::FLOAT_WRONG_FORMAT); ASSERT_EQ(config.parseScale(invalid_str2), StatusCode::FLOAT_WRONG_FORMAT); ASSERT_EQ(config.parseScale(invalid_str3), StatusCode::FLOAT_WRONG_FORMAT); + ASSERT_EQ(config.parseScale(invalid_str4), StatusCode::FLOAT_WRONG_FORMAT); + ASSERT_EQ(config.parseScale(invalid_str5), StatusCode::FLOAT_WRONG_FORMAT); } TEST(ModelConfig, parseColorFormatParameter) { diff --git a/src/test/ovmsconfig_test.cpp b/src/test/ovmsconfig_test.cpp index 2c5c35ecc8..044cf0b7f4 100644 --- a/src/test/ovmsconfig_test.cpp +++ b/src/test/ovmsconfig_test.cpp @@ -2433,9 +2433,9 @@ TEST(OvmsConfigTest, positiveSingle) { "--layout", "nchw:nhwc", "--mean", - "{123.675,116.28,103.53}", + "[123.675,116.28,103.53]", "--scale", - "{58.395,57.12,57.375}", + "[58.395,57.12,57.375]", "--color_format", "BGR", "--model_version_policy", @@ -2483,8 +2483,8 @@ TEST(OvmsConfigTest, positiveSingle) { EXPECT_EQ(config.batchSize(), "(3:5)"); EXPECT_EQ(config.shape(), "(3:5,5:6)"); EXPECT_EQ(config.layout(), "nchw:nhwc"); - EXPECT_EQ(config.means(), "{123.675,116.28,103.53}"); - EXPECT_EQ(config.scales(), "{58.395,57.12,57.375}"); + EXPECT_EQ(config.means(), "[123.675,116.28,103.53]"); + EXPECT_EQ(config.scales(), "[58.395,57.12,57.375]"); EXPECT_EQ(config.colorFormat(), "BGR"); EXPECT_EQ(config.modelVersionPolicy(), "setting"); EXPECT_EQ(config.nireq(), 2); From 4cf011d91737ccb74aece1d0825de84286d39405 Mon Sep 17 00:00:00 2001 From: Pawel Date: Thu, 8 Jan 2026 10:56:24 +0100 Subject: [PATCH 13/16] deleting venv --- demos/using_onnx_model/venv/bin/Activate.ps1 | 247 ------------------ demos/using_onnx_model/venv/bin/activate | 69 ----- demos/using_onnx_model/venv/bin/activate.csh | 26 -- demos/using_onnx_model/venv/bin/activate.fish | 69 ----- demos/using_onnx_model/venv/bin/f2py | 8 - demos/using_onnx_model/venv/bin/normalizer | 8 - demos/using_onnx_model/venv/bin/pip | 8 - demos/using_onnx_model/venv/bin/pip3 | 8 - demos/using_onnx_model/venv/bin/pip3.10 | 8 - demos/using_onnx_model/venv/bin/python | 1 - demos/using_onnx_model/venv/bin/python3 | 1 - demos/using_onnx_model/venv/bin/python3.10 | 1 - demos/using_onnx_model/venv/lib64 | 1 - demos/using_onnx_model/venv/pyvenv.cfg | 3 - 14 files changed, 458 deletions(-) delete mode 100644 demos/using_onnx_model/venv/bin/Activate.ps1 delete mode 100644 demos/using_onnx_model/venv/bin/activate delete mode 100644 demos/using_onnx_model/venv/bin/activate.csh delete mode 100644 demos/using_onnx_model/venv/bin/activate.fish delete mode 100755 demos/using_onnx_model/venv/bin/f2py delete mode 100755 demos/using_onnx_model/venv/bin/normalizer delete mode 100755 demos/using_onnx_model/venv/bin/pip delete mode 100755 demos/using_onnx_model/venv/bin/pip3 delete mode 100755 demos/using_onnx_model/venv/bin/pip3.10 delete mode 120000 demos/using_onnx_model/venv/bin/python delete mode 120000 demos/using_onnx_model/venv/bin/python3 delete mode 120000 demos/using_onnx_model/venv/bin/python3.10 delete mode 120000 demos/using_onnx_model/venv/lib64 delete mode 100644 demos/using_onnx_model/venv/pyvenv.cfg diff --git a/demos/using_onnx_model/venv/bin/Activate.ps1 b/demos/using_onnx_model/venv/bin/Activate.ps1 deleted file mode 100644 index b49d77ba44..0000000000 --- a/demos/using_onnx_model/venv/bin/Activate.ps1 +++ /dev/null @@ -1,247 +0,0 @@ -<# -.Synopsis -Activate a Python virtual environment for the current PowerShell session. - -.Description -Pushes the python executable for a virtual environment to the front of the -$Env:PATH environment variable and sets the prompt to signify that you are -in a Python virtual environment. Makes use of the command line switches as -well as the `pyvenv.cfg` file values present in the virtual environment. - -.Parameter VenvDir -Path to the directory that contains the virtual environment to activate. The -default value for this is the parent of the directory that the Activate.ps1 -script is located within. - -.Parameter Prompt -The prompt prefix to display when this virtual environment is activated. By -default, this prompt is the name of the virtual environment folder (VenvDir) -surrounded by parentheses and followed by a single space (ie. '(.venv) '). - -.Example -Activate.ps1 -Activates the Python virtual environment that contains the Activate.ps1 script. - -.Example -Activate.ps1 -Verbose -Activates the Python virtual environment that contains the Activate.ps1 script, -and shows extra information about the activation as it executes. - -.Example -Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv -Activates the Python virtual environment located in the specified location. - -.Example -Activate.ps1 -Prompt "MyPython" -Activates the Python virtual environment that contains the Activate.ps1 script, -and prefixes the current prompt with the specified string (surrounded in -parentheses) while the virtual environment is active. - -.Notes -On Windows, it may be required to enable this Activate.ps1 script by setting the -execution policy for the user. You can do this by issuing the following PowerShell -command: - -PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser - -For more information on Execution Policies: -https://go.microsoft.com/fwlink/?LinkID=135170 - -#> -Param( - [Parameter(Mandatory = $false)] - [String] - $VenvDir, - [Parameter(Mandatory = $false)] - [String] - $Prompt -) - -<# Function declarations --------------------------------------------------- #> - -<# -.Synopsis -Remove all shell session elements added by the Activate script, including the -addition of the virtual environment's Python executable from the beginning of -the PATH variable. - -.Parameter NonDestructive -If present, do not remove this function from the global namespace for the -session. - -#> -function global:deactivate ([switch]$NonDestructive) { - # Revert to original values - - # The prior prompt: - if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { - Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt - Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT - } - - # The prior PYTHONHOME: - if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { - Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME - Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME - } - - # The prior PATH: - if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { - Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH - Remove-Item -Path Env:_OLD_VIRTUAL_PATH - } - - # Just remove the VIRTUAL_ENV altogether: - if (Test-Path -Path Env:VIRTUAL_ENV) { - Remove-Item -Path env:VIRTUAL_ENV - } - - # Just remove VIRTUAL_ENV_PROMPT altogether. - if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { - Remove-Item -Path env:VIRTUAL_ENV_PROMPT - } - - # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: - if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { - Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force - } - - # Leave deactivate function in the global namespace if requested: - if (-not $NonDestructive) { - Remove-Item -Path function:deactivate - } -} - -<# -.Description -Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the -given folder, and returns them in a map. - -For each line in the pyvenv.cfg file, if that line can be parsed into exactly -two strings separated by `=` (with any amount of whitespace surrounding the =) -then it is considered a `key = value` line. The left hand string is the key, -the right hand is the value. - -If the value starts with a `'` or a `"` then the first and last character is -stripped from the value before being captured. - -.Parameter ConfigDir -Path to the directory that contains the `pyvenv.cfg` file. -#> -function Get-PyVenvConfig( - [String] - $ConfigDir -) { - Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" - - # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). - $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue - - # An empty map will be returned if no config file is found. - $pyvenvConfig = @{ } - - if ($pyvenvConfigPath) { - - Write-Verbose "File exists, parse `key = value` lines" - $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath - - $pyvenvConfigContent | ForEach-Object { - $keyval = $PSItem -split "\s*=\s*", 2 - if ($keyval[0] -and $keyval[1]) { - $val = $keyval[1] - - # Remove extraneous quotations around a string value. - if ("'""".Contains($val.Substring(0, 1))) { - $val = $val.Substring(1, $val.Length - 2) - } - - $pyvenvConfig[$keyval[0]] = $val - Write-Verbose "Adding Key: '$($keyval[0])'='$val'" - } - } - } - return $pyvenvConfig -} - - -<# Begin Activate script --------------------------------------------------- #> - -# Determine the containing directory of this script -$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition -$VenvExecDir = Get-Item -Path $VenvExecPath - -Write-Verbose "Activation script is located in path: '$VenvExecPath'" -Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" -Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" - -# Set values required in priority: CmdLine, ConfigFile, Default -# First, get the location of the virtual environment, it might not be -# VenvExecDir if specified on the command line. -if ($VenvDir) { - Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" -} -else { - Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." - $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") - Write-Verbose "VenvDir=$VenvDir" -} - -# Next, read the `pyvenv.cfg` file to determine any required value such -# as `prompt`. -$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir - -# Next, set the prompt from the command line, or the config file, or -# just use the name of the virtual environment folder. -if ($Prompt) { - Write-Verbose "Prompt specified as argument, using '$Prompt'" -} -else { - Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" - if ($pyvenvCfg -and $pyvenvCfg['prompt']) { - Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" - $Prompt = $pyvenvCfg['prompt']; - } - else { - Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" - Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" - $Prompt = Split-Path -Path $venvDir -Leaf - } -} - -Write-Verbose "Prompt = '$Prompt'" -Write-Verbose "VenvDir='$VenvDir'" - -# Deactivate any currently active virtual environment, but leave the -# deactivate function in place. -deactivate -nondestructive - -# Now set the environment variable VIRTUAL_ENV, used by many tools to determine -# that there is an activated venv. -$env:VIRTUAL_ENV = $VenvDir - -if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { - - Write-Verbose "Setting prompt to '$Prompt'" - - # Set the prompt to include the env name - # Make sure _OLD_VIRTUAL_PROMPT is global - function global:_OLD_VIRTUAL_PROMPT { "" } - Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT - New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt - - function global:prompt { - Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " - _OLD_VIRTUAL_PROMPT - } - $env:VIRTUAL_ENV_PROMPT = $Prompt -} - -# Clear PYTHONHOME -if (Test-Path -Path Env:PYTHONHOME) { - Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME - Remove-Item -Path Env:PYTHONHOME -} - -# Add the venv to the PATH -Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH -$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/demos/using_onnx_model/venv/bin/activate b/demos/using_onnx_model/venv/bin/activate deleted file mode 100644 index 38e73213ca..0000000000 --- a/demos/using_onnx_model/venv/bin/activate +++ /dev/null @@ -1,69 +0,0 @@ -# This file must be used with "source bin/activate" *from bash* -# you cannot run it directly - -deactivate () { - # reset old environment variables - if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then - PATH="${_OLD_VIRTUAL_PATH:-}" - export PATH - unset _OLD_VIRTUAL_PATH - fi - if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then - PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" - export PYTHONHOME - unset _OLD_VIRTUAL_PYTHONHOME - fi - - # This should detect bash and zsh, which have a hash command that must - # be called to get it to forget past commands. Without forgetting - # past commands the $PATH changes we made may not be respected - if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then - hash -r 2> /dev/null - fi - - if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then - PS1="${_OLD_VIRTUAL_PS1:-}" - export PS1 - unset _OLD_VIRTUAL_PS1 - fi - - unset VIRTUAL_ENV - unset VIRTUAL_ENV_PROMPT - if [ ! "${1:-}" = "nondestructive" ] ; then - # Self destruct! - unset -f deactivate - fi -} - -# unset irrelevant variables -deactivate nondestructive - -VIRTUAL_ENV=/opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv -export VIRTUAL_ENV - -_OLD_VIRTUAL_PATH="$PATH" -PATH="$VIRTUAL_ENV/"bin":$PATH" -export PATH - -# unset PYTHONHOME if set -# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) -# could use `if (set -u; : $PYTHONHOME) ;` in bash -if [ -n "${PYTHONHOME:-}" ] ; then - _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" - unset PYTHONHOME -fi - -if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then - _OLD_VIRTUAL_PS1="${PS1:-}" - PS1='(venv) '"${PS1:-}" - export PS1 - VIRTUAL_ENV_PROMPT='(venv) ' - export VIRTUAL_ENV_PROMPT -fi - -# This should detect bash and zsh, which have a hash command that must -# be called to get it to forget past commands. Without forgetting -# past commands the $PATH changes we made may not be respected -if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then - hash -r 2> /dev/null -fi diff --git a/demos/using_onnx_model/venv/bin/activate.csh b/demos/using_onnx_model/venv/bin/activate.csh deleted file mode 100644 index 773558a25b..0000000000 --- a/demos/using_onnx_model/venv/bin/activate.csh +++ /dev/null @@ -1,26 +0,0 @@ -# This file must be used with "source bin/activate.csh" *from csh*. -# You cannot run it directly. -# Created by Davide Di Blasi . -# Ported to Python 3.3 venv by Andrew Svetlov - -alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' - -# Unset irrelevant variables. -deactivate nondestructive - -setenv VIRTUAL_ENV /opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv - -set _OLD_VIRTUAL_PATH="$PATH" -setenv PATH "$VIRTUAL_ENV/"bin":$PATH" - - -set _OLD_VIRTUAL_PROMPT="$prompt" - -if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then - set prompt = '(venv) '"$prompt" - setenv VIRTUAL_ENV_PROMPT '(venv) ' -endif - -alias pydoc python -m pydoc - -rehash diff --git a/demos/using_onnx_model/venv/bin/activate.fish b/demos/using_onnx_model/venv/bin/activate.fish deleted file mode 100644 index 6d8b558ab1..0000000000 --- a/demos/using_onnx_model/venv/bin/activate.fish +++ /dev/null @@ -1,69 +0,0 @@ -# This file must be used with "source /bin/activate.fish" *from fish* -# (https://fishshell.com/); you cannot run it directly. - -function deactivate -d "Exit virtual environment and return to normal shell environment" - # reset old environment variables - if test -n "$_OLD_VIRTUAL_PATH" - set -gx PATH $_OLD_VIRTUAL_PATH - set -e _OLD_VIRTUAL_PATH - end - if test -n "$_OLD_VIRTUAL_PYTHONHOME" - set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME - set -e _OLD_VIRTUAL_PYTHONHOME - end - - if test -n "$_OLD_FISH_PROMPT_OVERRIDE" - set -e _OLD_FISH_PROMPT_OVERRIDE - # prevents error when using nested fish instances (Issue #93858) - if functions -q _old_fish_prompt - functions -e fish_prompt - functions -c _old_fish_prompt fish_prompt - functions -e _old_fish_prompt - end - end - - set -e VIRTUAL_ENV - set -e VIRTUAL_ENV_PROMPT - if test "$argv[1]" != "nondestructive" - # Self-destruct! - functions -e deactivate - end -end - -# Unset irrelevant variables. -deactivate nondestructive - -set -gx VIRTUAL_ENV /opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv - -set -gx _OLD_VIRTUAL_PATH $PATH -set -gx PATH "$VIRTUAL_ENV/"bin $PATH - -# Unset PYTHONHOME if set. -if set -q PYTHONHOME - set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME - set -e PYTHONHOME -end - -if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" - # fish uses a function instead of an env var to generate the prompt. - - # Save the current fish_prompt function as the function _old_fish_prompt. - functions -c fish_prompt _old_fish_prompt - - # With the original prompt function renamed, we can override with our own. - function fish_prompt - # Save the return status of the last command. - set -l old_status $status - - # Output the venv prompt; color taken from the blue of the Python logo. - printf "%s%s%s" (set_color 4B8BBE) '(venv) ' (set_color normal) - - # Restore the return status of the previous command. - echo "exit $old_status" | . - # Output the original/"old" prompt. - _old_fish_prompt - end - - set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" - set -gx VIRTUAL_ENV_PROMPT '(venv) ' -end diff --git a/demos/using_onnx_model/venv/bin/f2py b/demos/using_onnx_model/venv/bin/f2py deleted file mode 100755 index 096d479fe0..0000000000 --- a/demos/using_onnx_model/venv/bin/f2py +++ /dev/null @@ -1,8 +0,0 @@ -#!/opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv/bin/python3 -# -*- coding: utf-8 -*- -import re -import sys -from numpy.f2py.f2py2e import main -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/demos/using_onnx_model/venv/bin/normalizer b/demos/using_onnx_model/venv/bin/normalizer deleted file mode 100755 index e77a52dc9e..0000000000 --- a/demos/using_onnx_model/venv/bin/normalizer +++ /dev/null @@ -1,8 +0,0 @@ -#!/opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv/bin/python3 -# -*- coding: utf-8 -*- -import re -import sys -from charset_normalizer.cli import cli_detect -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) - sys.exit(cli_detect()) diff --git a/demos/using_onnx_model/venv/bin/pip b/demos/using_onnx_model/venv/bin/pip deleted file mode 100755 index 0fe5b4850e..0000000000 --- a/demos/using_onnx_model/venv/bin/pip +++ /dev/null @@ -1,8 +0,0 @@ -#!/opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv/bin/python3 -# -*- coding: utf-8 -*- -import re -import sys -from pip._internal.cli.main import main -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/demos/using_onnx_model/venv/bin/pip3 b/demos/using_onnx_model/venv/bin/pip3 deleted file mode 100755 index 0fe5b4850e..0000000000 --- a/demos/using_onnx_model/venv/bin/pip3 +++ /dev/null @@ -1,8 +0,0 @@ -#!/opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv/bin/python3 -# -*- coding: utf-8 -*- -import re -import sys -from pip._internal.cli.main import main -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/demos/using_onnx_model/venv/bin/pip3.10 b/demos/using_onnx_model/venv/bin/pip3.10 deleted file mode 100755 index 0fe5b4850e..0000000000 --- a/demos/using_onnx_model/venv/bin/pip3.10 +++ /dev/null @@ -1,8 +0,0 @@ -#!/opt/home/przepeck/repos/model_server0/demos/using_onnx_model/venv/bin/python3 -# -*- coding: utf-8 -*- -import re -import sys -from pip._internal.cli.main import main -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/demos/using_onnx_model/venv/bin/python b/demos/using_onnx_model/venv/bin/python deleted file mode 120000 index b8a0adbbb9..0000000000 --- a/demos/using_onnx_model/venv/bin/python +++ /dev/null @@ -1 +0,0 @@ -python3 \ No newline at end of file diff --git a/demos/using_onnx_model/venv/bin/python3 b/demos/using_onnx_model/venv/bin/python3 deleted file mode 120000 index 79ab74b1e1..0000000000 --- a/demos/using_onnx_model/venv/bin/python3 +++ /dev/null @@ -1 +0,0 @@ -/usr/local/bin/python3 \ No newline at end of file diff --git a/demos/using_onnx_model/venv/bin/python3.10 b/demos/using_onnx_model/venv/bin/python3.10 deleted file mode 120000 index b8a0adbbb9..0000000000 --- a/demos/using_onnx_model/venv/bin/python3.10 +++ /dev/null @@ -1 +0,0 @@ -python3 \ No newline at end of file diff --git a/demos/using_onnx_model/venv/lib64 b/demos/using_onnx_model/venv/lib64 deleted file mode 120000 index 7951405f85..0000000000 --- a/demos/using_onnx_model/venv/lib64 +++ /dev/null @@ -1 +0,0 @@ -lib \ No newline at end of file diff --git a/demos/using_onnx_model/venv/pyvenv.cfg b/demos/using_onnx_model/venv/pyvenv.cfg deleted file mode 100644 index 7a355ea6b0..0000000000 --- a/demos/using_onnx_model/venv/pyvenv.cfg +++ /dev/null @@ -1,3 +0,0 @@ -home = /usr/local/bin -include-system-site-packages = false -version = 3.10.12 From 3b17de93df00e80ec7204c60c0aaccd870a3b115 Mon Sep 17 00:00:00 2001 From: Pawel Date: Thu, 8 Jan 2026 13:26:38 +0100 Subject: [PATCH 14/16] format --- src/config.hpp | 4 +-- src/modelconfig.cpp | 4 +-- src/modelconfig.hpp | 35 +++++++++---------- src/modelinstance.cpp | 10 +++--- src/modelmanager.cpp | 6 ++-- src/test/c_api_tests.cpp | 66 +++++++++++++++++++---------------- src/test/modelconfig_test.cpp | 6 ++-- 7 files changed, 68 insertions(+), 63 deletions(-) diff --git a/src/config.hpp b/src/config.hpp index 04756e463f..0b9ad1a663 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -199,13 +199,13 @@ class Config { */ const std::string& layout() const; - /** + /** * @brief Get means * * @return const std::string& */ const std::string& means() const; - /** + /** * @brief Get scales * * @return const std::string& diff --git a/src/modelconfig.cpp b/src/modelconfig.cpp index 375f8922ea..6d4dd24a54 100644 --- a/src/modelconfig.cpp +++ b/src/modelconfig.cpp @@ -455,7 +455,7 @@ Status ModelConfig::parseFloatArrayOrValue(const std::string& str, float_vec_or_ erase_spaces(upperCaseCommand); - if ((*upperCaseCommand.begin() == '[' && *upperCaseCommand.rbegin() == ']') || + if ((*upperCaseCommand.begin() == '[' && *upperCaseCommand.rbegin() == ']') || (*upperCaseCommand.begin() == '(' && *upperCaseCommand.rbegin() == ')')) { auto commandWithoutBraces = upperCaseCommand.substr(1, upperCaseCommand.size() - 2); std::vector vals; @@ -476,7 +476,7 @@ Status ModelConfig::parseFloatArrayOrValue(const std::string& str, float_vec_or_ } Status ModelConfig::parseMean(const std::string& command) { - return parseFloatArrayOrValue(command, this->meanValues); + return parseFloatArrayOrValue(command, this->meanValues); } Status ModelConfig::parseScale(const std::string& command) { diff --git a/src/modelconfig.hpp b/src/modelconfig.hpp index 69d7534c92..68697fce85 100644 --- a/src/modelconfig.hpp +++ b/src/modelconfig.hpp @@ -202,17 +202,17 @@ class ModelConfig { */ std::string customLoaderOptionsStr; - /** + /** * @brief meanValues mean preprocessing parameters */ float_vec_or_value_t meanValues = 0.0f; - /** + /** * @brief scaleValues scale preprocessing parameters */ float_vec_or_value_t scaleValues = 1.0f; - /** + /** * @brief colorFormat color format preprocessing parameter */ ov::preprocess::ColorFormat colorFormat = ov::preprocess::ColorFormat::RGB; @@ -693,26 +693,25 @@ class ModelConfig { */ Status parseMean(const std::string& command); - /** + /** * @brief Parses value from string and extracts scales info * * @param string * * @return status */ - Status parseScale(const std::string& command); + Status parseScale(const std::string& command); - /** + /** * @brief Parses value from string and extracts color format * * @param string * * @return status */ - Status parseColorFormat(const std::string& command); - + Status parseColorFormat(const std::string& command); - /** + /** * @brief Parses value from string and extracts float value * * @param string @@ -720,9 +719,9 @@ class ModelConfig { * * @return status */ - Status parseFloat(const std::string& str, float& value); + Status parseFloat(const std::string& str, float& value); - /** + /** * @brief Parses value from string and extracts float value or array of float values * * @param string @@ -730,9 +729,9 @@ class ModelConfig { * * @return status */ - Status parseFloatArrayOrValue(const std::string& str, float_vec_or_value_t& values); - - /** + Status parseFloatArrayOrValue(const std::string& str, float_vec_or_value_t& values); + + /** * @brief Parses value from string and extracts array of float values * * @param string @@ -740,7 +739,7 @@ class ModelConfig { * * @return status */ - Status parseFloatArray(const std::string& str, std::vector& values); + Status parseFloatArray(const std::string& str, std::vector& values); /** * @brief Returns true if any input shape specified in shapes map is in AUTO mode @@ -862,7 +861,7 @@ class ModelConfig { this->layout = LayoutConfiguration(); } - /** + /** * @brief Get the get scales * * @return const float_vec_or_value_t& @@ -871,7 +870,7 @@ class ModelConfig { return this->scaleValues; } - /** + /** * @brief Get the get means * * @return const float_vec_or_value_t& @@ -880,7 +879,7 @@ class ModelConfig { return this->meanValues; } - /** + /** * @brief Get the get color format * * @return const ov::preprocess::ColorFormat& diff --git a/src/modelinstance.cpp b/src/modelinstance.cpp index 0b1a85582b..1e4ba40006 100644 --- a/src/modelinstance.cpp +++ b/src/modelinstance.cpp @@ -240,7 +240,7 @@ static void applyScaleOrMeanPreprocessing(ov::preprocess::PrePostProcessor& prep static Status applyPreprocessingConfiguration(ov::preprocess::PrePostProcessor& preproc, const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion) { OV_LOGGER("ov::preprocess::PrePostProcessor& preproc, const ModelConfig& config, std::shared_ptr& model"); - + try { ovms::float_vec_or_value_t preprocessingScale = config.getScales(); ovms::float_vec_or_value_t preprocessingMean = config.getMeans(); @@ -249,12 +249,12 @@ static Status applyPreprocessingConfiguration(ov::preprocess::PrePostProcessor& OV_LOGGER("Applying color format for model: {}, version: {}", modelName, modelVersion); preproc.input().tensor().set_color_format(colorFormat); preproc.input().preprocess().convert_color(colorFormat); - + OV_LOGGER("Applying mean configuration: {} for model: {}, version: {}", modelName, modelVersion); applyScaleOrMeanPreprocessing(preproc, preprocessingMean, false); OV_LOGGER("Applying scale configuration: {} for model: {}, version: {}", modelName, modelVersion); applyScaleOrMeanPreprocessing(preproc, preprocessingScale, true); - + } catch (const ov::Exception& e) { SPDLOG_LOGGER_ERROR(modelmanager_logger, "Failed to configure input preprocessing configuration for model:{}; version:{}; from OpenVINO with error:{}", modelName, @@ -401,7 +401,7 @@ static Status applyLayoutConfiguration(ov::preprocess::PrePostProcessor& preproc return StatusCode::OK; } -Status ModelInstance::applyPreprocessing(const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion){ +Status ModelInstance::applyPreprocessing(const ModelConfig& config, std::shared_ptr& model, const std::string& modelName, model_version_t modelVersion) { OV_LOGGER("ov::Model: {}, ov::preprocess::PrePostProcessor(ov::Model)", reinterpret_cast(model.get())); SPDLOG_LOGGER_DEBUG(modelmanager_logger, "Applying preprocessing configuration"); ov::preprocess::PrePostProcessor preproc(model); @@ -413,7 +413,7 @@ Status ModelInstance::applyPreprocessing(const ModelConfig& config, std::shared_ return status; } - status = applyPreprocessingConfiguration(preproc, config, model, modelName, modelVersion);//there should be also condition + status = applyPreprocessingConfiguration(preproc, config, model, modelName, modelVersion); //there should be also condition if (!status.ok()) { SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during preprocessing configuration"); return status; diff --git a/src/modelmanager.cpp b/src/modelmanager.cpp index 991729b0e6..b483ac3443 100644 --- a/src/modelmanager.cpp +++ b/src/modelmanager.cpp @@ -316,15 +316,15 @@ Status ModelManager::startFromConfig() { SPDLOG_LOGGER_ERROR(modelmanager_logger, "Couldn't parse mean parameter"); return status; } - + status = modelConfig.parseScale(config.scales()); - if (!status.ok()) { + if (!status.ok()) { SPDLOG_LOGGER_ERROR(modelmanager_logger, "Couldn't parse scale parameter"); return status; } status = modelConfig.parseColorFormat(config.colorFormat()); - if (!status.ok()) { + if (!status.ok()) { SPDLOG_LOGGER_ERROR(modelmanager_logger, "Couldn't parse color format parameter"); return status; } diff --git a/src/test/c_api_tests.cpp b/src/test/c_api_tests.cpp index 10b86d98d8..7504fa03ee 100644 --- a/src/test/c_api_tests.cpp +++ b/src/test/c_api_tests.cpp @@ -58,6 +58,9 @@ static void testDefaultSingleModelOptions(ModelsSettingsImpl* modelsSettings) { EXPECT_EQ(modelsSettings->batchSize, ""); EXPECT_EQ(modelsSettings->shape, ""); EXPECT_EQ(modelsSettings->layout, ""); + EXPECT_EQ(modelsSettings->mean, ""); + EXPECT_EQ(modelsSettings->scale, ""); + EXPECT_EQ(modelsSettings->colorFormat, ""); EXPECT_EQ(modelsSettings->modelVersionPolicy, ""); EXPECT_EQ(modelsSettings->nireq, 0); EXPECT_EQ(modelsSettings->targetDevice, ""); @@ -214,6 +217,9 @@ TEST(CAPIConfigTest, MultiModelConfiguration) { EXPECT_EQ(cfg.batchSize(), ""); EXPECT_EQ(cfg.shape(), ""); EXPECT_EQ(cfg.layout(), ""); + EXPECT_EQ(cfg.means(), ""); + EXPECT_EQ(cfg.scales(), ""); + EXPECT_EQ(cfg.colorFormat(), ""); EXPECT_EQ(cfg.modelVersionPolicy(), ""); EXPECT_EQ(cfg.nireq(), 0); EXPECT_EQ(cfg.targetDevice(), "CPU"); @@ -1926,12 +1932,12 @@ struct CallbackUnblockingAndCheckingStruct : CallbackUnblockingStruct { float expectedValue{-1231571}; }; -static void callbackCheckingIfErrorReported(OVMS_InferenceResponse* response, uint32_t flag, void* userStruct) { - SPDLOG_DEBUG("Using callback: callbackCheckingIfErrorReported!"); - EXPECT_NE(flag, 0); - CallbackUnblockingAndCheckingStruct* callbackStruct = reinterpret_cast(userStruct); - callbackStruct->signal.set_value(); -} +// static void callbackCheckingIfErrorReported(OVMS_InferenceResponse* response, uint32_t flag, void* userStruct) { +// SPDLOG_DEBUG("Using callback: callbackCheckingIfErrorReported!"); +// EXPECT_NE(flag, 0); +// CallbackUnblockingAndCheckingStruct* callbackStruct = reinterpret_cast(userStruct); +// callbackStruct->signal.set_value(); +// } static void callbackUnblockingAndCheckingResponse(OVMS_InferenceResponse* response, uint32_t flag, void* userStruct) { EXPECT_EQ(flag, 0); SPDLOG_DEBUG("Using callback: callbackUnblockingAndFreeingRequest!"); @@ -1993,27 +1999,27 @@ TEST_F(CAPIInference, AsyncWithCallbackDummy) { } SPDLOG_INFO("Using callbacks!"); } -TEST_F(CAPIInference, AsyncErrorHandling) { - ov::Core core; - MockModelInstanceWithSetOutputInfo instance(core); - instance.loadModel(DUMMY_MODEL_CONFIG); - std::unique_ptr unloadGuard; // we do not need it to be set - ovms::InferenceRequest request("dummy", 0); - std::vector in(10, INITIAL_VALUE); - request.addInput(DUMMY_MODEL_INPUT_NAME, OVMS_DATATYPE_FP32, DUMMY_MODEL_SHAPE.data(), DUMMY_MODEL_SHAPE.size()); - request.setInputBuffer(DUMMY_MODEL_INPUT_NAME, in.data(), DUMMY_MODEL_SHAPE[1] * sizeof(float), OVMS_BUFFERTYPE_CPU, 0); - ovms::InferenceResponse response; - auto outputInfo = instance.getOutputsInfo(); - outputInfo["NOT_EXISTING"] = std::make_shared("BADUMTSSS", ovms::Precision::UNDEFINED, shape_t{}); - instance.waitForLoaded(0, unloadGuard); - CallbackUnblockingAndCheckingStruct callbackStruct; - auto unblockSignal = callbackStruct.signal.get_future(); - request.setCompletionCallback(callbackCheckingIfErrorReported, &callbackStruct); - instance.setOutputsInfo(outputInfo); - auto status = ovms::modelInferAsync(instance, &request, unloadGuard); - EXPECT_EQ(status, ovms::StatusCode::OK) << status.string(); - unblockSignal.get(); - std::this_thread::sleep_for(std::chrono::seconds(1)); - unloadGuard.reset(); - instance.retireModel(); -} +// TEST_F(CAPIInference, AsyncErrorHandling) { +// ov::Core core; +// MockModelInstanceWithSetOutputInfo instance(core); +// instance.loadModel(DUMMY_MODEL_CONFIG); +// std::unique_ptr unloadGuard; // we do not need it to be set +// ovms::InferenceRequest request("dummy", 0); +// std::vector in(10, INITIAL_VALUE); +// request.addInput(DUMMY_MODEL_INPUT_NAME, OVMS_DATATYPE_FP32, DUMMY_MODEL_SHAPE.data(), DUMMY_MODEL_SHAPE.size()); +// request.setInputBuffer(DUMMY_MODEL_INPUT_NAME, in.data(), DUMMY_MODEL_SHAPE[1] * sizeof(float), OVMS_BUFFERTYPE_CPU, 0); +// ovms::InferenceResponse response; +// auto outputInfo = instance.getOutputsInfo(); +// outputInfo["NOT_EXISTING"] = std::make_shared("BADUMTSSS", ovms::Precision::UNDEFINED, shape_t{}); +// instance.waitForLoaded(0, unloadGuard); +// CallbackUnblockingAndCheckingStruct callbackStruct; +// auto unblockSignal = callbackStruct.signal.get_future(); +// request.setCompletionCallback(callbackCheckingIfErrorReported, &callbackStruct); +// instance.setOutputsInfo(outputInfo); +// auto status = ovms::modelInferAsync(instance, &request, unloadGuard); +// EXPECT_EQ(status, ovms::StatusCode::OK) << status.string(); +// unblockSignal.get(); +// std::this_thread::sleep_for(std::chrono::seconds(1)); +// unloadGuard.reset(); +// instance.retireModel(); +// } diff --git a/src/test/modelconfig_test.cpp b/src/test/modelconfig_test.cpp index eca7d8567e..33c5cf9782 100644 --- a/src/test/modelconfig_test.cpp +++ b/src/test/modelconfig_test.cpp @@ -199,7 +199,7 @@ TEST(ModelConfig, parseLayoutParam_multi) { TEST(ModelConfig, parseMeanParameter) { using namespace ovms; ModelConfig config; - + std::string valid_str1 = "[123.675,116.28,103.53]"; std::string valid_str2 = " [ 0.0 , 255.0 ,128.5 ] "; std::string valid_str3 = "1.0"; @@ -229,7 +229,7 @@ TEST(ModelConfig, parseMeanParameter) { TEST(ModelConfig, parseScaleParameter) { using namespace ovms; ModelConfig config; - + std::string valid_str1 = "[123.675,116.28,103.53]"; std::string valid_str2 = " [ 0.0 , 255.0 ,128.5 ] "; std::string valid_str3 = "1.0"; @@ -259,7 +259,7 @@ TEST(ModelConfig, parseScaleParameter) { TEST(ModelConfig, parseColorFormatParameter) { using namespace ovms; ModelConfig config; - + std::string valid_str1 = "RGB"; std::string valid_str2 = "BGR"; std::string valid_str3 = "GRAY"; From 5ea2daa789c162fefee7f269e813e0b101243293 Mon Sep 17 00:00:00 2001 From: Pawel Date: Thu, 8 Jan 2026 13:30:50 +0100 Subject: [PATCH 15/16] spelling whitelist corrected --- spelling-whitelist.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spelling-whitelist.txt b/spelling-whitelist.txt index 9d76388fea..afe42f0a06 100644 --- a/spelling-whitelist.txt +++ b/spelling-whitelist.txt @@ -9,12 +9,12 @@ src/shape.cpp:438: strIn src/shape.cpp:488: strIn src/shape.cpp:507: strIn src/shape.hpp:121: strIn -src/test/modelconfig_test.cpp:473: OptionA -src/test/modelconfig_test.cpp:479: OptionA -src/test/modelconfig_test.cpp:485: OptionA -src/test/modelconfig_test.cpp:491: OptionA -src/test/modelconfig_test.cpp:497: OptionA -src/test/modelconfig_test.cpp:503: OptionA +src/test/modelconfig_test.cpp:565: OptionA +src/test/modelconfig_test.cpp:571: OptionA +src/test/modelconfig_test.cpp:577: OptionA +src/test/modelconfig_test.cpp:583: OptionA +src/test/modelconfig_test.cpp:589: OptionA +src/test/modelconfig_test.cpp:595: OptionA src/test/modelinstance_test.cpp:1093: THROUGHTPUT third_party/aws-sdk-cpp/aws-sdk-cpp.bz WORKSPACE:98: thirdparty From f923274451ce02afd1412dc3d38751333f07455b Mon Sep 17 00:00:00 2001 From: Pawel Date: Thu, 8 Jan 2026 14:18:09 +0100 Subject: [PATCH 16/16] cpplint --- src/modelinstance.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/modelinstance.cpp b/src/modelinstance.cpp index 1e4ba40006..5760026fa6 100644 --- a/src/modelinstance.cpp +++ b/src/modelinstance.cpp @@ -254,7 +254,6 @@ static Status applyPreprocessingConfiguration(ov::preprocess::PrePostProcessor& applyScaleOrMeanPreprocessing(preproc, preprocessingMean, false); OV_LOGGER("Applying scale configuration: {} for model: {}, version: {}", modelName, modelVersion); applyScaleOrMeanPreprocessing(preproc, preprocessingScale, true); - } catch (const ov::Exception& e) { SPDLOG_LOGGER_ERROR(modelmanager_logger, "Failed to configure input preprocessing configuration for model:{}; version:{}; from OpenVINO with error:{}", modelName, @@ -413,7 +412,7 @@ Status ModelInstance::applyPreprocessing(const ModelConfig& config, std::shared_ return status; } - status = applyPreprocessingConfiguration(preproc, config, model, modelName, modelVersion); //there should be also condition + status = applyPreprocessingConfiguration(preproc, config, model, modelName, modelVersion); if (!status.ok()) { SPDLOG_LOGGER_ERROR(modelmanager_logger, "Error during preprocessing configuration"); return status;