Repository: openvinotoolkit/openvino
Pull request #29224: [Template]: Fix property test for template plugin(#21756)
Author: login: Simonwzm
Labels: name: category: IE Tests
description: OpenVINO Test: plugins and common
name: ExternalPR
description: External contributor
name: category: TEMPLATE
description: OpenVINO Template plugin
Created: 2025-03-01T04:37:20Z | Merged: 2025-04-16T07:02:47Z

### Details: Modify following properties in template plugin and its test case
- Addition
  - enable_hyper_threading
  - enable_cpu_pinning
  - scheduling_core_type
  - compilation_num_threads
  - inference_num_threads
- Deletion
  - enable_mmap (refer to previous related [draft](https://github.com/openvinotoolkit/openvino/pull/23212))

### Tickets:
 - #21756 
 
 ### Test results
All tests have passed following this test command `ov_api_conformance_tests --gtest_filter=*OVCheckSetSupportedRWMetricsPropsTests*ChangeCorrectProperties*properties=* --device=TEMPLATE`

If there is any mistakes or concerns, please let me know and I will keep up with those.



Diff:
diff --git a/src/plugins/template/src/config.cpp b/src/plugins/template/src/config.cpp
index 3b3a78e40c4bb5..34e13fe06aa9e2 100644
--- a/src/plugins/template/src/config.cpp
+++ b/src/plugins/template/src/config.cpp
@@ -82,6 +82,43 @@ Configuration::Configuration(const ov::AnyMap& config, const Configuration& defa
             model_priority = value.as<ov::hint::Priority>();
         } else if (ov::cache_encryption_callbacks == key) {
             encryption_callbacks = value.as<EncryptionCallbacks>();
+        } else if (ov::hint::scheduling_core_type == key) {
+            try {
+                schedulingCoreType = value.as<ov::hint::SchedulingCoreType>();
+            } catch (const std::exception&) {
+                OPENVINO_THROW("Wrong value ", value.as<ov::hint::SchedulingCoreType>(), "for property key ", key);
+            }
+        } else if (key == ov::hint::enable_hyper_threading) {
+            try {
+                enableHyperThreading = value.as<bool>();
+            } catch (ov::Exception&) {
+                OPENVINO_THROW("Wrong value ",
+                               value.as<std::string>(),
+                               "for property key ",
+                               key,
+                               ". Expected only true/false.");
+            }
+        } else if (key == ov::hint::enable_cpu_pinning.name()) {
+            try {
+                enableCpuPinning = value.as<bool>();
+            } catch (ov::Exception&) {
+                OPENVINO_THROW("Wrong value ",
+                               value.as<std::string>(),
+                               "for property key ",
+                               key,
+                               ". Expected only true/false.");
+            }
+        } else if (ov::compilation_num_threads.name() == key) {
+            int val;
+            try {
+                val = value.as<int>();
+            } catch (const std::exception&) {
+                OPENVINO_THROW("Wrong value for property key ", key, ". Expected only positive numbers (#threads)");
+            }
+            if (val < 0) {
+                OPENVINO_THROW("Wrong value for property key ", key, ". Expected only positive numbers (#threads)");
+            }
+            compilation_thread_num = val;
         } else if (ov::weights_path == key) {
             weights_path = value.as<std::string>();
             if (!weights_path.empty()) {
@@ -122,6 +159,14 @@ ov::Any Configuration::Get(const std::string& name) const {
         return log_level;
     } else if (name == ov::hint::model_priority) {
         return model_priority;
+    } else if (name == ov::compilation_num_threads) {
+        return {std::to_string(compilation_thread_num)};
+    } else if (name == ov::hint::scheduling_core_type) {
+        return schedulingCoreType;
+    } else if (name == ov::hint::enable_cpu_pinning) {
+        return enableCpuPinning;
+    } else if (name == ov::hint::enable_hyper_threading) {
+        return enableHyperThreading;
     } else if (name == ov::weights_path) {
         return weights_path.string();
     } else if (name == ov::internal::compiled_model_runtime_properties) {
diff --git a/src/plugins/template/src/config.hpp b/src/plugins/template/src/config.hpp
index c3cd8ff191347a..c462df442422e4 100644
--- a/src/plugins/template/src/config.hpp
+++ b/src/plugins/template/src/config.hpp
@@ -49,6 +49,10 @@ struct Configuration {
 
     ov::hint::Priority model_priority = ov::hint::Priority::DEFAULT;
 
+    ov::hint::SchedulingCoreType schedulingCoreType = ov::hint::SchedulingCoreType::ANY_CORE;
+    bool enableCpuPinning = false;
+    bool enableHyperThreading = false;
+    int compilation_thread_num = 1;
     EncryptionCallbacks encryption_callbacks{};
     std::filesystem::path weights_path{};
     AnyMap compiled_model_runtime_properties{};
diff --git a/src/plugins/template/src/plugin.cpp b/src/plugins/template/src/plugin.cpp
index cbd1f07f74eb7d..5e69d20c310220 100644
--- a/src/plugins/template/src/plugin.cpp
+++ b/src/plugins/template/src/plugin.cpp
@@ -347,6 +347,11 @@ ov::Any ov::template_plugin::Plugin::get_property(const std::string& name, const
             ov::template_plugin::disable_transformations,
             ov::log::level,
             ov::hint::model_priority,
+            ov::hint::enable_hyper_threading,
+            ov::hint::enable_cpu_pinning,
+            ov::hint::scheduling_core_type,
+            ov::compilation_num_threads,
+            ov::inference_num_threads,
             ov::weights_path,
             ov::cache_mode,
         };
diff --git a/src/tests/functional/plugin/shared/src/behavior/ov_plugin/properties_tests.cpp b/src/tests/functional/plugin/shared/src/behavior/ov_plugin/properties_tests.cpp
index 85fb0ccf4d51a0..e1e169b26cf0a3 100644
--- a/src/tests/functional/plugin/shared/src/behavior/ov_plugin/properties_tests.cpp
+++ b/src/tests/functional/plugin/shared/src/behavior/ov_plugin/properties_tests.cpp
@@ -352,11 +352,6 @@ OVPropertiesTestsWithCompileModelProps::getRWOptionalPropertiesValues(
         }
     }
 
-    if (props.empty() || std::find(props.begin(), props.end(), ov::enable_mmap.name()) != props.end()) {
-        res.push_back({ov::enable_mmap(true)});
-        res.push_back({ov::enable_mmap(false)});
-    }
-
     if (props.empty() || std::find(props.begin(), props.end(), ov::log::level.name()) != props.end()) {
         ov::log::Level log_levels[] = {ov::log::Level::NO , ov::log::Level::ERR, ov::log::Level::WARNING,
                                        ov::log::Level::INFO, ov::log::Level::DEBUG, ov::log::Level::TRACE};
@@ -396,10 +391,6 @@ OVPropertiesTestsWithCompileModelProps::getWrongRWOptionalPropertiesValues(
         res.push_back({{ov::hint::scheduling_core_type.name(), -1}});
     }
 
-    if (props.empty() || std::find(props.begin(), props.end(), ov::enable_mmap.name()) != props.end()) {
-        res.push_back({{ov::enable_mmap.name(), -10}});
-    }
-
     if (props.empty() || std::find(props.begin(), props.end(), ov::log::level.name()) != props.end()) {
         res.push_back({{ov::log::level.name(), -3}});
     }


Reviews:
user: login: praasz
body: Thanks for contribution, could update the PR and resolve conflicts?
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T08:45:49Z
user: login: praasz
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-11T05:22:12Z

Review comments:
diff_hunk: @@ -41,7 +41,7 @@ Configuration::Configuration(const ov::AnyMap& config, const Configuration& defa
         } else if (ov::inference_num_threads.name() == key) {
             int val;
             try {
-                val = value.as<int>();
+                val = value.as<decltype(ov::inference_num_threads)::value_type>();
path: src/plugins/template/src/config.cpp
user: login: praasz
body: I think it should not be required as numerical values can be converted to other numerical type.
created_at: 2025-04-02T08:37:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -85,6 +85,45 @@ Configuration::Configuration(const ov::AnyMap& config, const Configuration& defa
             model_priority = value.as<ov::hint::Priority>();
         } else if (ov::cache_encryption_callbacks == key) {
             encryption_callbacks = value.as<EncryptionCallbacks>();
+        } else if (ov::hint::scheduling_core_type == key) {
+            try {
+                schedulingCoreType = value.as<ov::hint::SchedulingCoreType>();
+            } catch (const std::exception&) {
+                OPENVINO_THROW("Wrong value ", value.as<ov::hint::SchedulingCoreType>(), "for property key ", key);
+            }
+        } else if (key == ov::hint::enable_hyper_threading.name()) {
path: src/plugins/template/src/config.cpp
user: login: praasz
body: ```suggestion
        } else if (key == ov::hint::enable_hyper_threading) {
```
property should be converted to name.
created_at: 2025-04-02T08:38:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -85,6 +85,45 @@ Configuration::Configuration(const ov::AnyMap& config, const Configuration& defa
             model_priority = value.as<ov::hint::Priority>();
         } else if (ov::cache_encryption_callbacks == key) {
             encryption_callbacks = value.as<EncryptionCallbacks>();
+        } else if (ov::hint::scheduling_core_type == key) {
+            try {
+                schedulingCoreType = value.as<ov::hint::SchedulingCoreType>();
+            } catch (const std::exception&) {
+                OPENVINO_THROW("Wrong value ", value.as<ov::hint::SchedulingCoreType>(), "for property key ", key);
+            }
+        } else if (key == ov::hint::enable_hyper_threading.name()) {
+            try {
+                enableHyperThreading = value.as<bool>();
+                changedHyperThreading = true;
path: src/plugins/template/src/config.cpp
user: login: praasz
body: What is purpose of this variable? It can be removed as not used.
created_at: 2025-04-02T08:40:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -48,6 +48,13 @@ struct Configuration {
 
     ov::hint::Priority model_priority = ov::hint::Priority::DEFAULT;
 
+    ov::hint::SchedulingCoreType schedulingCoreType = ov::hint::SchedulingCoreType::ANY_CORE;
+    bool enableCpuPinning = false;
+    bool changedCpuPinning = false;
+    bool enableHyperThreading = false;
+    bool changedHyperThreading = false;
path: src/plugins/template/src/config.hpp
user: login: praasz
body: ```suggestion
    bool enableCpuPinning = false;
    bool enableHyperThreading = false;
```
created_at: 2025-04-02T08:41:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -352,10 +352,10 @@ OVPropertiesTestsWithCompileModelProps::getRWOptionalPropertiesValues(
         }
     }
 
-    if (props.empty() || std::find(props.begin(), props.end(), ov::enable_mmap.name()) != props.end()) {
-        res.push_back({ov::enable_mmap(true)});
-        res.push_back({ov::enable_mmap(false)});
-    }
+    // if (props.empty() || std::find(props.begin(), props.end(), ov::enable_mmap.name()) != props.end()) {
+    //     res.push_back({ov::enable_mmap(true)});
+    //     res.push_back({ov::enable_mmap(false)});
+    // }
path: src/tests/functional/plugin/shared/src/behavior/ov_plugin/properties_tests.cpp
user: login: praasz
body: Remove it?
created_at: 2025-04-02T08:41:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -396,9 +396,9 @@ OVPropertiesTestsWithCompileModelProps::getWrongRWOptionalPropertiesValues(
         res.push_back({{ov::hint::scheduling_core_type.name(), -1}});
     }
 
-    if (props.empty() || std::find(props.begin(), props.end(), ov::enable_mmap.name()) != props.end()) {
-        res.push_back({{ov::enable_mmap.name(), -10}});
-    }
+    // if (props.empty() || std::find(props.begin(), props.end(), ov::enable_mmap.name()) != props.end()) {
+    //     res.push_back({{ov::enable_mmap.name(), -10}});
+    // }
path: src/tests/functional/plugin/shared/src/behavior/ov_plugin/properties_tests.cpp
user: login: praasz
body: Remove it?
created_at: 2025-04-02T08:41:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -85,6 +85,45 @@ Configuration::Configuration(const ov::AnyMap& config, const Configuration& defa
             model_priority = value.as<ov::hint::Priority>();
         } else if (ov::cache_encryption_callbacks == key) {
             encryption_callbacks = value.as<EncryptionCallbacks>();
+        } else if (ov::hint::scheduling_core_type == key) {
+            try {
+                schedulingCoreType = value.as<ov::hint::SchedulingCoreType>();
+            } catch (const std::exception&) {
+                OPENVINO_THROW("Wrong value ", value.as<ov::hint::SchedulingCoreType>(), "for property key ", key);
+            }
+        } else if (key == ov::hint::enable_hyper_threading.name()) {
+            try {
+                enableHyperThreading = value.as<bool>();
+                changedHyperThreading = true;
+            } catch (ov::Exception&) {
+                OPENVINO_THROW("Wrong value ",
+                               value.as<std::string>(),
+                               "for property key ",
+                               ov::hint::enable_hyper_threading.name(),
+                               ". Expected only true/false.");
+            }
+        } else if (key == ov::hint::enable_cpu_pinning.name()) {
+            try {
+                enableCpuPinning = value.as<bool>();
+                changedCpuPinning = true;
+            } catch (ov::Exception&) {
+                OPENVINO_THROW("Wrong value ",
+                               value.as<std::string>(),
+                               "for property key ",
+                               ov::hint::enable_cpu_pinning.name(),
path: src/plugins/template/src/config.cpp
user: login: praasz
body: ```suggestion
                               key,
```
created_at: 2025-04-02T08:42:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -85,6 +85,45 @@ Configuration::Configuration(const ov::AnyMap& config, const Configuration& defa
             model_priority = value.as<ov::hint::Priority>();
         } else if (ov::cache_encryption_callbacks == key) {
             encryption_callbacks = value.as<EncryptionCallbacks>();
+        } else if (ov::hint::scheduling_core_type == key) {
+            try {
+                schedulingCoreType = value.as<ov::hint::SchedulingCoreType>();
+            } catch (const std::exception&) {
+                OPENVINO_THROW("Wrong value ", value.as<ov::hint::SchedulingCoreType>(), "for property key ", key);
+            }
+        } else if (key == ov::hint::enable_hyper_threading.name()) {
+            try {
+                enableHyperThreading = value.as<bool>();
+                changedHyperThreading = true;
+            } catch (ov::Exception&) {
+                OPENVINO_THROW("Wrong value ",
+                               value.as<std::string>(),
+                               "for property key ",
+                               ov::hint::enable_hyper_threading.name(),
path: src/plugins/template/src/config.cpp
user: login: praasz
body: ```suggestion
                               key,
```
created_at: 2025-04-02T08:43:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -85,6 +85,45 @@ Configuration::Configuration(const ov::AnyMap& config, const Configuration& defa
             model_priority = value.as<ov::hint::Priority>();
         } else if (ov::cache_encryption_callbacks == key) {
             encryption_callbacks = value.as<EncryptionCallbacks>();
+        } else if (ov::hint::scheduling_core_type == key) {
+            try {
+                schedulingCoreType = value.as<ov::hint::SchedulingCoreType>();
+            } catch (const std::exception&) {
+                OPENVINO_THROW("Wrong value ", value.as<ov::hint::SchedulingCoreType>(), "for property key ", key);
+            }
+        } else if (key == ov::hint::enable_hyper_threading.name()) {
+            try {
+                enableHyperThreading = value.as<bool>();
+                changedHyperThreading = true;
+            } catch (ov::Exception&) {
+                OPENVINO_THROW("Wrong value ",
+                               value.as<std::string>(),
+                               "for property key ",
+                               ov::hint::enable_hyper_threading.name(),
+                               ". Expected only true/false.");
+            }
+        } else if (key == ov::hint::enable_cpu_pinning.name()) {
+            try {
+                enableCpuPinning = value.as<bool>();
+                changedCpuPinning = true;
+            } catch (ov::Exception&) {
+                OPENVINO_THROW("Wrong value ",
+                               value.as<std::string>(),
+                               "for property key ",
+                               ov::hint::enable_cpu_pinning.name(),
+                               ". Expected only true/false.");
+            }
+        } else if (ov::compilation_num_threads.name() == key) {
+            int val;
+            try {
+                val = value.as<decltype(ov::compilation_num_threads)::value_type>();
path: src/plugins/template/src/config.cpp
user: login: praasz
body: ```suggestion
                val = value.as<int>();
```
If property is numerical it should be converted
created_at: 2025-04-02T08:44:19Z
author_association: CONTRIBUTOR

PR comments:
user: login: Simonwzm
created_at: 2025-04-09T14:19:30Z
body: I have merged with master branch and updated PR as requested.
author_association: CONTRIBUTOR
user: login: praasz
created_at: 2025-04-11T05:20:30Z
body: build_jenkins
author_association: CONTRIBUTOR
user: login: mlukasze
created_at: 2025-04-15T06:52:23Z
body: build_jenkins
author_association: CONTRIBUTOR