Update the logic of benchmark app property setting (#16427)
* 1. refine the logic to ov::device::properties setting. 2. the config overrides will be performed if same config setting is came from CMD line.-a Signed-off-by: Wang, Yang <yang4.wang@intel.com> * Update configuration sample file within README.md. * Update. * Update. * 1. Update configuration example file within REAMDME.md for Python version. 2. implement the config DEVICE_PROPERTIES value convertation between the string type and dictionary of Python type. 3. Update the configuration file loading and dumping logic. Signed-off-by: Wang, Yang <yang4.wang@intel.com> * Update. * Update. * Update. * Update. * Update. * 1. Enable configs to be interchangeable between C++ and Python. 2. Update perf_count showing logic. Signed-off-by: Wang, Yang <yang4.wang@intel.com> * Revert the logic of showing show performance counters. * Update help msg for loading config option. --------- Signed-off-by: Wang, Yang <yang4.wang@intel.com>
This commit is contained in:
@@ -217,27 +217,18 @@ Running the application with the ``-h`` or ``--help`` option yields the followin
|
||||
-exec_graph_path Optional. Path to a file where to store executable graph information serialized.
|
||||
-dump_config Optional. Path to JSON file to dump IE parameters, which were set by application.
|
||||
-load_config Optional. Path to JSON file to load custom IE parameters. Please note, command line parameters have higher priority then parameters from configuration file.
|
||||
Example 1: a simple JSON file for HW device with primary properties.
|
||||
{
|
||||
"CPU": {"NUM_STREAMS": "3", "PERF_COUNT": "NO"}
|
||||
}
|
||||
Example 2: a simple JSON file for meta device(AUTO/MULTI) with HW device properties.
|
||||
{
|
||||
"AUTO": {
|
||||
"PERFORMANCE_HINT": "",
|
||||
"PERF_COUNT": "NO",
|
||||
"DEVICE_PROPERTIES": {
|
||||
"CPU": {
|
||||
"INFERENCE_PRECISION_HINT": "f32",
|
||||
"NUM_STREAMS": "3"
|
||||
},
|
||||
"GPU": {
|
||||
"INFERENCE_PRECISION_HINT": "f32",
|
||||
"NUM_STREAMS": "5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Example 1: a simple JSON file for HW device with primary properties.
|
||||
{
|
||||
"CPU": {"NUM_STREAMS": "3", "PERF_COUNT": "NO"}
|
||||
}
|
||||
Example 2: a simple JSON file for meta device(AUTO/MULTI) with HW device properties.
|
||||
{
|
||||
"AUTO": {
|
||||
"PERFORMANCE_HINT": "THROUGHPUT",
|
||||
"PERF_COUNT": "NO",
|
||||
"DEVICE_PROPERTIES": "{CPU:{INFERENCE_PRECISION_HINT:f32,NUM_STREAMS:3},GPU:{INFERENCE_PRECISION_HINT:f32,NUM_STREAMS:5}}"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Running the application with the empty list of options yields the usage message given above and an error message.
|
||||
|
||||
@@ -245,18 +245,10 @@ static const char load_config_message[] =
|
||||
"properties.\n"
|
||||
" {\n"
|
||||
" \"AUTO\": {\n"
|
||||
" \"PERFORMANCE_HINT\": \"\",\n"
|
||||
" \"PERFORMANCE_HINT\": \"THROUGHPUT\",\n"
|
||||
" \"PERF_COUNT\": \"NO\",\n"
|
||||
" \"DEVICE_PROPERTIES\": {\n"
|
||||
" \"CPU\": {\n"
|
||||
" \"INFERENCE_PRECISION_HINT\": \"f32\",\n"
|
||||
" \"NUM_STREAMS\": \"3\"\n"
|
||||
" },\n"
|
||||
" \"GPU\": {\n"
|
||||
" \"INFERENCE_PRECISION_HINT\": \"f32\",\n"
|
||||
" \"NUM_STREAMS\": \"5\"\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" \"DEVICE_PROPERTIES\": "
|
||||
"\"{CPU:{INFERENCE_PRECISION_HINT:f32,NUM_STREAMS:3},GPU:{INFERENCE_PRECISION_HINT:f32,NUM_STREAMS:5}}\"\n"
|
||||
" }\n"
|
||||
" }";
|
||||
|
||||
|
||||
@@ -162,7 +162,6 @@ void setDeviceProperty(ov::Core& core,
|
||||
std::string& device,
|
||||
ov::AnyMap& device_config,
|
||||
const std::pair<std::string, ov::Any>& property,
|
||||
std::map<std::string, bool>& is_dev_set_property,
|
||||
const std::pair<std::string, ov::Any>& config = {}) {
|
||||
auto supported_properties = core.get_property(device, ov::supported_properties);
|
||||
auto supported = [&](const std::string& key) {
|
||||
@@ -179,18 +178,7 @@ void setDeviceProperty(ov::Core& core,
|
||||
if (device_property.first.empty())
|
||||
return;
|
||||
|
||||
if (device_config.find(device) == device_config.end() || // device properties not existed
|
||||
(config.first.empty() && // not setting default value to property
|
||||
(!FLAGS_load_config.empty() &&
|
||||
is_dev_set_property[device]))) { // device properties loaded from file and overwrite is not happened
|
||||
is_dev_set_property[device] = false;
|
||||
device_config.erase(device);
|
||||
device_config.insert(ov::device::properties(device, device_property));
|
||||
} else {
|
||||
auto& properties = device_config[device].as<ov::AnyMap>();
|
||||
// property present in device properties has higher priority than property set with default value
|
||||
properties.emplace(device_property);
|
||||
}
|
||||
update_device_properties_setting(device, device_config, device_property);
|
||||
}
|
||||
|
||||
void warn_if_no_batch(const benchmark_app::InputsInfo& first_inputs) {
|
||||
@@ -285,10 +273,6 @@ int main(int argc, char* argv[]) {
|
||||
// Parse devices
|
||||
auto devices = parse_devices(device_name);
|
||||
|
||||
std::map<std::string, bool> is_dev_set_property = {};
|
||||
// initialize flags to ensure ov::device::properties should only be set once per device.
|
||||
for (auto& dev : devices)
|
||||
is_dev_set_property[dev] = true;
|
||||
// Parse nstreams per device
|
||||
std::map<std::string, std::string> device_nstreams = parse_value_per_device(devices, FLAGS_nstreams);
|
||||
std::map<std::string, std::string> device_infer_precision =
|
||||
@@ -296,10 +280,8 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
// Load device config file if specified
|
||||
std::map<std::string, ov::AnyMap> config;
|
||||
bool is_load_config = false;
|
||||
if (!FLAGS_load_config.empty()) {
|
||||
load_config(FLAGS_load_config, config);
|
||||
is_load_config = true;
|
||||
}
|
||||
|
||||
/** This vector stores paths to the processed images with input names**/
|
||||
@@ -377,20 +359,22 @@ int main(int argc, char* argv[]) {
|
||||
// Update config per device according to command line parameters
|
||||
for (auto& device : devices) {
|
||||
auto& device_config = config[device];
|
||||
|
||||
// high-level performance modes
|
||||
if (!device_config.count(ov::hint::performance_mode.name())) {
|
||||
device_config.emplace(ov::hint::performance_mode(get_performance_hint(device, core)));
|
||||
auto ov_perf_hint = get_performance_hint(device, core);
|
||||
if (isFlagSetInCommandLine("hint")) {
|
||||
// apply command line hint setting and override if hint exists
|
||||
device_config[ov::hint::performance_mode.name()] = ov_perf_hint;
|
||||
} else {
|
||||
// keep hint setting in the config if no hint setting from command line
|
||||
device_config.emplace(ov::hint::performance_mode(ov_perf_hint));
|
||||
}
|
||||
auto ov_perf_hint = device_config.at(ov::hint::performance_mode.name()).as<ov::hint::PerformanceMode>();
|
||||
|
||||
if (FLAGS_nireq != 0)
|
||||
device_config.emplace(ov::hint::num_requests(unsigned(FLAGS_nireq)));
|
||||
device_config[ov::hint::num_requests.name()] = unsigned(FLAGS_nireq);
|
||||
|
||||
// Set performance counter
|
||||
if (isFlagSetInCommandLine("pc")) {
|
||||
// set to user defined value
|
||||
device_config.emplace(ov::enable_profiling(FLAGS_pc));
|
||||
device_config[ov::enable_profiling.name()] = FLAGS_pc;
|
||||
} else if (device_config.count(ov::enable_profiling.name()) &&
|
||||
(device_config.at(ov::enable_profiling.name()).as<bool>())) {
|
||||
slog::warn << "Performance counters for " << device
|
||||
@@ -399,18 +383,18 @@ int main(int argc, char* argv[]) {
|
||||
FLAGS_report_type == sortDetailedCntReport) {
|
||||
slog::warn << "Turn on performance counters for " << device << " device since report type is "
|
||||
<< FLAGS_report_type << "." << slog::endl;
|
||||
device_config.emplace(ov::enable_profiling(true));
|
||||
device_config[ov::enable_profiling.name()] = true;
|
||||
} else if (!FLAGS_exec_graph_path.empty()) {
|
||||
slog::warn << "Turn on performance counters for " << device << " device due to execution graph dumping."
|
||||
<< slog::endl;
|
||||
device_config.emplace(ov::enable_profiling(true));
|
||||
device_config[ov::enable_profiling.name()] = true;
|
||||
} else if (!FLAGS_pcsort.empty()) {
|
||||
slog::warn << "Turn on sorted performance counters for " << device << " device since pcsort value is "
|
||||
<< FLAGS_pcsort << "." << slog::endl;
|
||||
device_config.emplace(ov::enable_profiling(true));
|
||||
device_config[ov::enable_profiling.name()] = true;
|
||||
} else {
|
||||
// set to default value
|
||||
device_config.emplace(ov::enable_profiling(FLAGS_pc));
|
||||
device_config[ov::enable_profiling.name()] = FLAGS_pc;
|
||||
}
|
||||
perf_counts = (device_config.at(ov::enable_profiling.name()).as<bool>()) ? true : perf_counts;
|
||||
|
||||
@@ -437,9 +421,7 @@ int main(int argc, char* argv[]) {
|
||||
key = ov::num_streams.name();
|
||||
update_device_config_for_virtual_device(it_device_nstreams->second,
|
||||
device_config,
|
||||
ov::num_streams,
|
||||
is_dev_set_property,
|
||||
is_load_config);
|
||||
ov::num_streams);
|
||||
} else {
|
||||
throw std::logic_error("Device " + device + " doesn't support config key '" + key + "' " +
|
||||
"and '" + ov::num_streams.name() + "'!" +
|
||||
@@ -472,7 +454,6 @@ int main(int argc, char* argv[]) {
|
||||
hwdevice,
|
||||
device_config,
|
||||
ov::num_streams(ov::streams::AUTO),
|
||||
is_dev_set_property,
|
||||
std::make_pair(key, value));
|
||||
}
|
||||
}
|
||||
@@ -492,9 +473,7 @@ int main(int argc, char* argv[]) {
|
||||
} else if (is_virtual_device(device)) {
|
||||
update_device_config_for_virtual_device(it_device_infer_precision->second,
|
||||
device_config,
|
||||
ov::hint::inference_precision,
|
||||
is_dev_set_property,
|
||||
is_load_config);
|
||||
ov::hint::inference_precision);
|
||||
} else {
|
||||
throw std::logic_error("Device " + device + " doesn't support config key '" +
|
||||
ov::hint::inference_precision.name() + "'! " +
|
||||
@@ -520,13 +499,13 @@ int main(int argc, char* argv[]) {
|
||||
: ov::affinity(fix_pin_option(FLAGS_pin));
|
||||
if (supported(property_name) || device_name == "AUTO") {
|
||||
// create nthreads/pin primary property for HW device or AUTO if -d is AUTO directly.
|
||||
device_config.emplace(property);
|
||||
device_config[property.first] = property.second;
|
||||
} else if (is_virtual) {
|
||||
// Create secondary property of -nthreads/-pin only for CPU if CPU device appears in the devices
|
||||
// list specified by -d.
|
||||
for (auto& device : hardware_devices) {
|
||||
if (device == "CPU")
|
||||
setDeviceProperty(core, device, device_config, property, is_dev_set_property);
|
||||
setDeviceProperty(core, device, device_config, property);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -121,6 +121,41 @@ bool is_virtual_device_found(const std::vector<std::string>& device_names) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void update_device_properties_setting(const std::string& device_name,
|
||||
ov::AnyMap& config,
|
||||
std::pair<std::string, ov::Any> device_property) {
|
||||
// overriding if property {key, value} is already existed in config["DEVICE_PROPERTIES"][device_name],
|
||||
// if not, insert this {key, value} into config["DEVICE_PROPERTIES"][device_name].
|
||||
|
||||
// check and create property {"DEVICE_PROPERTIES": ov::AnyMap{hw_device, ov::AnyMap{}}} if not exist in config
|
||||
if (config.find(ov::device::properties.name()) == config.end()) {
|
||||
config[ov::device::properties.name()] = ov::AnyMap{};
|
||||
config[ov::device::properties.name()].as<ov::AnyMap>().insert({device_name, ov::AnyMap{device_property}});
|
||||
return;
|
||||
}
|
||||
|
||||
// because of legacy API 1.0. eg the config from JSON file.
|
||||
if (config[ov::device::properties.name()].is<std::string>()) {
|
||||
config[ov::device::properties.name()] = config[ov::device::properties.name()].as<ov::AnyMap>();
|
||||
}
|
||||
|
||||
auto& device_properties = config[ov::device::properties.name()].as<ov::AnyMap>();
|
||||
if (device_properties.find(device_name) == device_properties.end()) {
|
||||
device_properties.insert({device_name, ov::AnyMap{device_property}});
|
||||
return;
|
||||
}
|
||||
|
||||
// because of legacy API 1.0. eg the config from JSON file.
|
||||
if (device_properties[device_name].is<std::string>()) {
|
||||
device_properties[device_name] = device_properties[device_name].as<ov::AnyMap>();
|
||||
}
|
||||
|
||||
auto& secondary_property = device_properties[device_name].as<ov::AnyMap>();
|
||||
// overwrite if this config existed
|
||||
secondary_property.erase(device_property.first);
|
||||
secondary_property.insert(device_property);
|
||||
}
|
||||
|
||||
std::vector<std::string> parse_devices(const std::string& device_string) {
|
||||
std::string comma_separated_devices = device_string;
|
||||
auto colon = comma_separated_devices.find(":");
|
||||
@@ -184,9 +219,7 @@ void parse_value_for_virtual_device(const std::string& device, std::map<std::str
|
||||
template <typename T>
|
||||
void update_device_config_for_virtual_device(const std::string& value,
|
||||
ov::AnyMap& device_config,
|
||||
ov::Property<T, ov::PropertyMutability::RW> property,
|
||||
std::map<std::string, bool>& is_dev_set_property,
|
||||
bool is_load_config) {
|
||||
ov::Property<T, ov::PropertyMutability::RW> property) {
|
||||
// check if the element contains the hardware device property
|
||||
if (split(value, ':').size() == 1) {
|
||||
device_config[property.name()] = value;
|
||||
@@ -198,52 +231,21 @@ void update_device_config_for_virtual_device(const std::string& value,
|
||||
for (const auto& it : devices_property) {
|
||||
const auto& device_name = it.first;
|
||||
const auto& device_value = it.second;
|
||||
if (device_config.find(ov::device::properties.name()) == device_config.end() ||
|
||||
(is_load_config && is_dev_set_property[device_name])) {
|
||||
// Create ov::device::properties with ov::num_stream/ov::hint::inference_precision and
|
||||
// 1. Insert this ov::device::properties into device config if this
|
||||
// ov::device::properties isn't existed. Otherwise,
|
||||
// 2. Replace the existed ov::device::properties within device config.
|
||||
is_dev_set_property[device_name] = false;
|
||||
device_config.erase(device_name);
|
||||
device_config[ov::device::properties.name()] = ov::AnyMap{};
|
||||
auto& secondary_property = device_config.at(ov::device::properties.name()).as<ov::AnyMap>();
|
||||
secondary_property[device_name] = ov::AnyMap{{property.name(), device_value}};
|
||||
} else {
|
||||
auto& secondary_property = device_config.at(ov::device::properties.name()).as<ov::AnyMap>();
|
||||
if (secondary_property.count(device_name)) {
|
||||
auto& device_property = secondary_property.at(device_name).as<ov::AnyMap>();
|
||||
device_property.emplace(property(device_value));
|
||||
} else {
|
||||
secondary_property[device_name] = ov::AnyMap{{property.name(), device_value}};
|
||||
}
|
||||
}
|
||||
update_device_properties_setting(device_name, device_config, property(device_value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update_device_config_for_virtual_device(const std::string& value,
|
||||
ov::AnyMap& device_config,
|
||||
ov::Property<ov::streams::Num, ov::PropertyMutability::RW> property,
|
||||
std::map<std::string, bool>& is_dev_set_property,
|
||||
bool is_load_config) {
|
||||
return update_device_config_for_virtual_device<ov::streams::Num>(value,
|
||||
device_config,
|
||||
property,
|
||||
is_dev_set_property,
|
||||
is_load_config);
|
||||
ov::Property<ov::streams::Num, ov::PropertyMutability::RW> property) {
|
||||
return update_device_config_for_virtual_device<ov::streams::Num>(value, device_config, property);
|
||||
}
|
||||
|
||||
void update_device_config_for_virtual_device(const std::string& value,
|
||||
ov::AnyMap& device_config,
|
||||
ov::Property<ov::element::Type, ov::PropertyMutability::RW> property,
|
||||
std::map<std::string, bool>& is_dev_set_property,
|
||||
bool is_load_config) {
|
||||
return update_device_config_for_virtual_device<ov::element::Type>(value,
|
||||
device_config,
|
||||
property,
|
||||
is_dev_set_property,
|
||||
is_load_config);
|
||||
ov::Property<ov::element::Type, ov::PropertyMutability::RW> property) {
|
||||
return update_device_config_for_virtual_device<ov::element::Type>(value, device_config, property);
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> parse_value_per_device(const std::vector<std::string>& devices,
|
||||
|
||||
@@ -60,6 +60,9 @@ using PartialShapes = std::map<std::string, ngraph::PartialShape>;
|
||||
|
||||
bool is_virtual_device(const std::string& device_name);
|
||||
bool is_virtual_device_found(const std::vector<std::string>& device_names);
|
||||
void update_device_properties_setting(const std::string& device_name,
|
||||
ov::AnyMap& config,
|
||||
std::pair<std::string, ov::Any> device_property);
|
||||
std::vector<std::string> parse_devices(const std::string& device_string);
|
||||
uint32_t device_default_device_duration_in_seconds(const std::string& device);
|
||||
std::map<std::string, std::string> parse_value_per_device(const std::vector<std::string>& devices,
|
||||
@@ -68,9 +71,7 @@ void parse_value_for_virtual_device(const std::string& device, std::map<std::str
|
||||
template <typename T>
|
||||
void update_device_config_for_virtual_device(const std::string& value,
|
||||
ov::AnyMap& device_config,
|
||||
ov::Property<T, ov::PropertyMutability::RW> property,
|
||||
std::map<std::string, bool>& is_dev_set_property,
|
||||
bool is_load_config = false);
|
||||
ov::Property<T, ov::PropertyMutability::RW> property);
|
||||
std::string get_shapes_string(const benchmark_app::PartialShapes& shapes);
|
||||
size_t get_batch_size(const benchmark_app::InputsInfo& inputs_info);
|
||||
std::vector<std::string> split(const std::string& s, char delim);
|
||||
|
||||
@@ -306,26 +306,17 @@ Running the application with the ``-h`` or ``--help`` option yields the followin
|
||||
Optional. Path to JSON file to load custom OpenVINO parameters.
|
||||
Please note, command line parameters have higher priority then parameters from configuration file.
|
||||
Example 1: a simple JSON file for HW device with primary properties.
|
||||
{
|
||||
"CPU": {"NUM_STREAMS": "3", "PERF_COUNT": "NO"}
|
||||
}
|
||||
{
|
||||
"CPU": {"NUM_STREAMS": "3", "PERF_COUNT": "NO"}
|
||||
}
|
||||
Example 2: a simple JSON file for meta device(AUTO/MULTI) with HW device properties.
|
||||
{
|
||||
"AUTO": {
|
||||
"PERFORMANCE_HINT": "",
|
||||
"PERF_COUNT": "NO",
|
||||
"DEVICE_PROPERTIES": {
|
||||
"CPU": {
|
||||
"INFERENCE_PRECISION_HINT": "f32",
|
||||
"NUM_STREAMS": "3"
|
||||
},
|
||||
"GPU": {
|
||||
"INFERENCE_PRECISION_HINT": "f32",
|
||||
"NUM_STREAMS": "5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"AUTO": {
|
||||
"PERFORMANCE_HINT": "THROUGHPUT",
|
||||
"PERF_COUNT": "NO",
|
||||
"DEVICE_PROPERTIES": "{CPU:{INFERENCE_PRECISION_HINT:f32,NUM_STREAMS:3},GPU:{INFERENCE_PRECISION_HINT:f32,NUM_STREAMS:5}}"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Running the application with the empty list of options yields the usage message given above and an error message.
|
||||
|
||||
@@ -71,15 +71,12 @@ def main():
|
||||
device_name = args.target_device
|
||||
|
||||
devices = parse_devices(device_name)
|
||||
is_dev_set_property = {device: True for device in devices}
|
||||
device_number_streams = parse_value_per_device(devices, args.number_streams, "nstreams")
|
||||
device_infer_precision = parse_value_per_device(devices, args.infer_precision, "infer_precision")
|
||||
|
||||
config = {}
|
||||
is_load_config = False
|
||||
if args.load_config:
|
||||
load_config(args.load_config, config)
|
||||
is_load_config = True
|
||||
|
||||
if is_network_compiled:
|
||||
logger.info("Model is compiled")
|
||||
@@ -108,7 +105,7 @@ def main():
|
||||
# --------------------- 3. Setting device configuration --------------------------------------------------------
|
||||
next_step()
|
||||
|
||||
def get_performance_hint(device) -> properties.hint.PerformanceMode:
|
||||
def set_performance_hint(device):
|
||||
perf_hint = properties.hint.PerformanceMode.UNDEFINED
|
||||
supported_properties = benchmark.core.get_property(device, properties.supported_properties())
|
||||
if properties.hint.performance_mode() in supported_properties:
|
||||
@@ -128,9 +125,10 @@ def main():
|
||||
perf_hint = properties.hint.PerformanceMode.THROUGHPUT if benchmark.api_type == "async" else properties.hint.PerformanceMode.LATENCY
|
||||
logger.warning(f"Performance hint was not explicitly specified in command line. " +
|
||||
f"Device({device}) performance hint will be set to {perf_hint}.")
|
||||
config[device][properties.hint.performance_mode()] = perf_hint
|
||||
else:
|
||||
logger.warning(f"Device {device} does not support performance hint property(-hint).")
|
||||
return perf_hint
|
||||
|
||||
|
||||
def get_device_type_from_name(name) :
|
||||
new_name = str(name)
|
||||
@@ -169,10 +167,7 @@ def main():
|
||||
config[device] = {}
|
||||
|
||||
## high-level performance modes
|
||||
if properties.hint.performance_mode() not in config[device].keys():
|
||||
config[device][properties.hint.performance_mode()] = get_performance_hint(device)
|
||||
|
||||
perf_hint = config[device][properties.hint.performance_mode()]
|
||||
set_performance_hint(device)
|
||||
|
||||
if is_flag_set_in_command_line('nireq'):
|
||||
config[device][properties.hint.num_requests()] = str(args.number_infer_requests)
|
||||
@@ -205,14 +200,6 @@ def main():
|
||||
## insert or append property into hw device properties list
|
||||
def update_configs(hw_device, property_name, property_value):
|
||||
(key, value) = properties.device.properties({hw_device:{property_name:property_value}})
|
||||
is_set_streams_auto = property_name == properties.num_streams() and property_value == properties.streams.Num.AUTO
|
||||
if not is_set_streams_auto and is_load_config and is_dev_set_property[hw_device] and hw_device in config[device].keys():
|
||||
# overwrite the device properties loaded from configuration file if
|
||||
# 1. not setting 'NUM_STREAMS' to default value 'AUTO',
|
||||
# 2. enable loading device properties from configuration file,
|
||||
# 3. device properties in config[device] is loaded from configuration file, and never setting device properties before
|
||||
is_dev_set_property[hw_device] = False
|
||||
del config[device][key]
|
||||
# add property into hw device properties list.
|
||||
if key not in config[device].keys():
|
||||
config[device][key] = value
|
||||
@@ -221,10 +208,10 @@ def main():
|
||||
if hw_device not in current_config.keys():
|
||||
current_config.update(value.get())
|
||||
else:
|
||||
current_device_config = current_config[hw_device].get()
|
||||
current_device_config = current_config[hw_device]
|
||||
for prop in value.get().items():
|
||||
current_device_config.update(prop[1].get())
|
||||
current_config[hw_device].set(current_device_config)
|
||||
current_device_config.update(prop[1])
|
||||
current_config[hw_device].update(current_device_config)
|
||||
config[device][key].set(current_config)
|
||||
|
||||
def update_device_config_for_virtual_device(value, config, key):
|
||||
@@ -326,7 +313,6 @@ def main():
|
||||
if device in device_number_streams.keys():
|
||||
del device_number_streams[device]
|
||||
|
||||
perf_counts = perf_counts
|
||||
device_config = {}
|
||||
for device in config:
|
||||
if benchmark.device.find(device) == 0:
|
||||
@@ -466,7 +452,7 @@ def main():
|
||||
if k == properties.device.properties():
|
||||
for device_key in value.keys():
|
||||
logger.info(f' {device_key}:')
|
||||
for k2, value2 in value.get(device_key).get().items():
|
||||
for k2, value2 in value.get(device_key).items():
|
||||
if k2 not in skip_keys:
|
||||
logger.info(f' {k2}: {value2}')
|
||||
else:
|
||||
|
||||
@@ -189,18 +189,9 @@ def parse_args():
|
||||
"Example 2: a simple JSON file for meta device(AUTO/MULTI) with HW device properties.\n"
|
||||
" {\n"
|
||||
" \"AUTO\": {\n"
|
||||
" \"PERFORMANCE_HINT\": \"\",\n"
|
||||
" \"PERFORMANCE_HINT\": \"THROUGHPUT\",\n"
|
||||
" \"PERF_COUNT\": \"NO\",\n"
|
||||
" \"DEVICE_PROPERTIES\": {\n"
|
||||
" \"CPU\": {\n"
|
||||
" \"INFERENCE_PRECISION_HINT\": \"f32\",\n"
|
||||
" \"NUM_STREAMS\": \"3\"\n"
|
||||
" },\n"
|
||||
" \"GPU\": {\n"
|
||||
" \"INFERENCE_PRECISION_HINT\": \"f32\",\n"
|
||||
" \"NUM_STREAMS\": \"5\"\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" \"DEVICE_PROPERTIES\": \"{CPU:{INFERENCE_PRECISION_HINT:f32,NUM_STREAMS:3},GPU:{INFERENCE_PRECISION_HINT:f32,NUM_STREAMS:5}}\"\n"
|
||||
" }\n"
|
||||
" }")
|
||||
parsed_args = parser.parse_args()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
from collections import defaultdict
|
||||
from datetime import timedelta
|
||||
import enum
|
||||
from openvino.runtime import Core, Model, PartialShape, Dimension, Layout, Type, serialize, properties
|
||||
from openvino.runtime import Core, Model, PartialShape, Dimension, Layout, Type, serialize, properties, OVAny
|
||||
from openvino.preprocess import PrePostProcessor
|
||||
|
||||
from .constants import DEVICE_DURATION_IN_SECS, UNKNOWN_DEVICE_TYPE, \
|
||||
@@ -758,12 +758,64 @@ def show_available_devices():
|
||||
print("\nAvailable target devices: ", (" ".join(Core().available_devices)))
|
||||
|
||||
|
||||
def device_properties_to_string(config):
|
||||
ret = "{"
|
||||
for k, v in config.items():
|
||||
if isinstance(v, dict):
|
||||
sub_str = "{"
|
||||
for sk, sv in v.items():
|
||||
if isinstance(sv, bool):
|
||||
sv = "YES" if sv else "NO"
|
||||
if isinstance(sv, properties.Affinity):
|
||||
sv = sv.name
|
||||
sub_str += "{0}:{1},".format(sk, sv)
|
||||
sub_str = sub_str[:-1]
|
||||
sub_str += "}"
|
||||
ret += "{0}:{1},".format(k, sub_str)
|
||||
else:
|
||||
ret += "{0}:{1},".format(k, v)
|
||||
ret = ret[:-1]
|
||||
ret += "}"
|
||||
return ret
|
||||
|
||||
|
||||
def string_to_device_properties(device_properties_str):
|
||||
ret = {}
|
||||
if not device_properties_str:
|
||||
return ret
|
||||
if not device_properties_str.startswith("{") or not device_properties_str.endswith("}"):
|
||||
raise Exception(
|
||||
"Failed to parse device properties. Value of device properties should be started with '{' and ended with '}'."
|
||||
"They are actually {} and {}".format(device_properties_str[0], device_properties_str[-1]))
|
||||
pattern = r'(\w+):({.+?}|[^,}]+)'
|
||||
pairs = re.findall(pattern, device_properties_str)
|
||||
for key, value in pairs:
|
||||
if value.startswith("{") and value.endswith("}"):
|
||||
value = value[1:-1]
|
||||
nested_pairs = re.findall(pattern, value)
|
||||
nested_dict = {}
|
||||
for nested_key, nested_value in nested_pairs:
|
||||
nested_dict[nested_key] = nested_value
|
||||
value = nested_dict
|
||||
ret[key] = value
|
||||
return ret
|
||||
|
||||
|
||||
def dump_config(filename, config):
|
||||
json_config = {}
|
||||
for device_name, device_config in config.items():
|
||||
json_config[device_name] = {}
|
||||
for key, value in device_config.items():
|
||||
value_string = value.name if isinstance(value, properties.hint.PerformanceMode) else str(value)
|
||||
if isinstance(value, OVAny) and (isinstance(value.value, dict)):
|
||||
value_string = device_properties_to_string(value.get())
|
||||
elif isinstance(value, (properties.hint.PerformanceMode, properties.Affinity)):
|
||||
value_string = value.name
|
||||
elif isinstance(value, OVAny):
|
||||
value_string = str(value.value)
|
||||
else:
|
||||
value_string = str(value)
|
||||
if isinstance(value, bool):
|
||||
value_string = "YES" if value else "NO"
|
||||
json_config[device_name][key] = value_string
|
||||
|
||||
with open(filename, 'w') as f:
|
||||
@@ -776,4 +828,9 @@ def load_config(filename, config):
|
||||
for device in original_config:
|
||||
config[device] = {}
|
||||
for property_name in original_config[device]:
|
||||
config[device][property_name] = original_config[device][property_name]
|
||||
property_value = original_config[device][property_name]
|
||||
if property_name == properties.device.properties():
|
||||
property_value = string_to_device_properties(property_value)
|
||||
elif property_value in ("YES", "NO"):
|
||||
property_value = True if property_value == "YES" else False
|
||||
config[device][property_name] = OVAny(property_value)
|
||||
|
||||
Reference in New Issue
Block a user