triton-model-analyzer 1.48.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- model_analyzer/__init__.py +15 -0
- model_analyzer/analyzer.py +448 -0
- model_analyzer/cli/__init__.py +15 -0
- model_analyzer/cli/cli.py +193 -0
- model_analyzer/config/__init__.py +15 -0
- model_analyzer/config/generate/__init__.py +15 -0
- model_analyzer/config/generate/automatic_model_config_generator.py +164 -0
- model_analyzer/config/generate/base_model_config_generator.py +352 -0
- model_analyzer/config/generate/brute_plus_binary_parameter_search_run_config_generator.py +164 -0
- model_analyzer/config/generate/brute_run_config_generator.py +154 -0
- model_analyzer/config/generate/concurrency_sweeper.py +75 -0
- model_analyzer/config/generate/config_generator_interface.py +52 -0
- model_analyzer/config/generate/coordinate.py +143 -0
- model_analyzer/config/generate/coordinate_data.py +86 -0
- model_analyzer/config/generate/generator_utils.py +116 -0
- model_analyzer/config/generate/manual_model_config_generator.py +187 -0
- model_analyzer/config/generate/model_config_generator_factory.py +92 -0
- model_analyzer/config/generate/model_profile_spec.py +74 -0
- model_analyzer/config/generate/model_run_config_generator.py +154 -0
- model_analyzer/config/generate/model_variant_name_manager.py +150 -0
- model_analyzer/config/generate/neighborhood.py +536 -0
- model_analyzer/config/generate/optuna_plus_concurrency_sweep_run_config_generator.py +141 -0
- model_analyzer/config/generate/optuna_run_config_generator.py +838 -0
- model_analyzer/config/generate/perf_analyzer_config_generator.py +312 -0
- model_analyzer/config/generate/quick_plus_concurrency_sweep_run_config_generator.py +130 -0
- model_analyzer/config/generate/quick_run_config_generator.py +753 -0
- model_analyzer/config/generate/run_config_generator_factory.py +329 -0
- model_analyzer/config/generate/search_config.py +112 -0
- model_analyzer/config/generate/search_dimension.py +73 -0
- model_analyzer/config/generate/search_dimensions.py +85 -0
- model_analyzer/config/generate/search_parameter.py +49 -0
- model_analyzer/config/generate/search_parameters.py +388 -0
- model_analyzer/config/input/__init__.py +15 -0
- model_analyzer/config/input/config_command.py +483 -0
- model_analyzer/config/input/config_command_profile.py +1747 -0
- model_analyzer/config/input/config_command_report.py +267 -0
- model_analyzer/config/input/config_defaults.py +236 -0
- model_analyzer/config/input/config_enum.py +83 -0
- model_analyzer/config/input/config_field.py +216 -0
- model_analyzer/config/input/config_list_generic.py +112 -0
- model_analyzer/config/input/config_list_numeric.py +151 -0
- model_analyzer/config/input/config_list_string.py +111 -0
- model_analyzer/config/input/config_none.py +71 -0
- model_analyzer/config/input/config_object.py +129 -0
- model_analyzer/config/input/config_primitive.py +81 -0
- model_analyzer/config/input/config_status.py +75 -0
- model_analyzer/config/input/config_sweep.py +83 -0
- model_analyzer/config/input/config_union.py +113 -0
- model_analyzer/config/input/config_utils.py +128 -0
- model_analyzer/config/input/config_value.py +243 -0
- model_analyzer/config/input/objects/__init__.py +15 -0
- model_analyzer/config/input/objects/config_model_profile_spec.py +325 -0
- model_analyzer/config/input/objects/config_model_report_spec.py +173 -0
- model_analyzer/config/input/objects/config_plot.py +198 -0
- model_analyzer/config/input/objects/config_protobuf_utils.py +101 -0
- model_analyzer/config/input/yaml_config_validator.py +82 -0
- model_analyzer/config/run/__init__.py +15 -0
- model_analyzer/config/run/model_run_config.py +313 -0
- model_analyzer/config/run/run_config.py +168 -0
- model_analyzer/constants.py +76 -0
- model_analyzer/device/__init__.py +15 -0
- model_analyzer/device/device.py +24 -0
- model_analyzer/device/gpu_device.py +87 -0
- model_analyzer/device/gpu_device_factory.py +248 -0
- model_analyzer/entrypoint.py +307 -0
- model_analyzer/log_formatter.py +65 -0
- model_analyzer/model_analyzer_exceptions.py +24 -0
- model_analyzer/model_manager.py +255 -0
- model_analyzer/monitor/__init__.py +15 -0
- model_analyzer/monitor/cpu_monitor.py +69 -0
- model_analyzer/monitor/dcgm/DcgmDiag.py +191 -0
- model_analyzer/monitor/dcgm/DcgmFieldGroup.py +83 -0
- model_analyzer/monitor/dcgm/DcgmGroup.py +815 -0
- model_analyzer/monitor/dcgm/DcgmHandle.py +141 -0
- model_analyzer/monitor/dcgm/DcgmJsonReader.py +69 -0
- model_analyzer/monitor/dcgm/DcgmReader.py +623 -0
- model_analyzer/monitor/dcgm/DcgmStatus.py +57 -0
- model_analyzer/monitor/dcgm/DcgmSystem.py +412 -0
- model_analyzer/monitor/dcgm/__init__.py +15 -0
- model_analyzer/monitor/dcgm/common/__init__.py +13 -0
- model_analyzer/monitor/dcgm/common/dcgm_client_cli_parser.py +194 -0
- model_analyzer/monitor/dcgm/common/dcgm_client_main.py +86 -0
- model_analyzer/monitor/dcgm/dcgm_agent.py +887 -0
- model_analyzer/monitor/dcgm/dcgm_collectd_plugin.py +369 -0
- model_analyzer/monitor/dcgm/dcgm_errors.py +395 -0
- model_analyzer/monitor/dcgm/dcgm_field_helpers.py +546 -0
- model_analyzer/monitor/dcgm/dcgm_fields.py +815 -0
- model_analyzer/monitor/dcgm/dcgm_fields_collectd.py +671 -0
- model_analyzer/monitor/dcgm/dcgm_fields_internal.py +29 -0
- model_analyzer/monitor/dcgm/dcgm_fluentd.py +45 -0
- model_analyzer/monitor/dcgm/dcgm_monitor.py +138 -0
- model_analyzer/monitor/dcgm/dcgm_prometheus.py +326 -0
- model_analyzer/monitor/dcgm/dcgm_structs.py +2357 -0
- model_analyzer/monitor/dcgm/dcgm_telegraf.py +65 -0
- model_analyzer/monitor/dcgm/dcgm_value.py +151 -0
- model_analyzer/monitor/dcgm/dcgmvalue.py +155 -0
- model_analyzer/monitor/dcgm/denylist_recommendations.py +573 -0
- model_analyzer/monitor/dcgm/pydcgm.py +47 -0
- model_analyzer/monitor/monitor.py +143 -0
- model_analyzer/monitor/remote_monitor.py +137 -0
- model_analyzer/output/__init__.py +15 -0
- model_analyzer/output/file_writer.py +63 -0
- model_analyzer/output/output_writer.py +42 -0
- model_analyzer/perf_analyzer/__init__.py +15 -0
- model_analyzer/perf_analyzer/genai_perf_config.py +206 -0
- model_analyzer/perf_analyzer/perf_analyzer.py +882 -0
- model_analyzer/perf_analyzer/perf_config.py +479 -0
- model_analyzer/plots/__init__.py +15 -0
- model_analyzer/plots/detailed_plot.py +266 -0
- model_analyzer/plots/plot_manager.py +224 -0
- model_analyzer/plots/simple_plot.py +213 -0
- model_analyzer/record/__init__.py +15 -0
- model_analyzer/record/gpu_record.py +68 -0
- model_analyzer/record/metrics_manager.py +887 -0
- model_analyzer/record/record.py +280 -0
- model_analyzer/record/record_aggregator.py +256 -0
- model_analyzer/record/types/__init__.py +15 -0
- model_analyzer/record/types/cpu_available_ram.py +93 -0
- model_analyzer/record/types/cpu_used_ram.py +93 -0
- model_analyzer/record/types/gpu_free_memory.py +96 -0
- model_analyzer/record/types/gpu_power_usage.py +107 -0
- model_analyzer/record/types/gpu_total_memory.py +96 -0
- model_analyzer/record/types/gpu_used_memory.py +96 -0
- model_analyzer/record/types/gpu_utilization.py +108 -0
- model_analyzer/record/types/inter_token_latency_avg.py +60 -0
- model_analyzer/record/types/inter_token_latency_base.py +74 -0
- model_analyzer/record/types/inter_token_latency_max.py +60 -0
- model_analyzer/record/types/inter_token_latency_min.py +60 -0
- model_analyzer/record/types/inter_token_latency_p25.py +60 -0
- model_analyzer/record/types/inter_token_latency_p50.py +60 -0
- model_analyzer/record/types/inter_token_latency_p75.py +60 -0
- model_analyzer/record/types/inter_token_latency_p90.py +60 -0
- model_analyzer/record/types/inter_token_latency_p95.py +60 -0
- model_analyzer/record/types/inter_token_latency_p99.py +60 -0
- model_analyzer/record/types/output_token_throughput.py +105 -0
- model_analyzer/record/types/perf_client_response_wait.py +97 -0
- model_analyzer/record/types/perf_client_send_recv.py +97 -0
- model_analyzer/record/types/perf_latency.py +111 -0
- model_analyzer/record/types/perf_latency_avg.py +60 -0
- model_analyzer/record/types/perf_latency_base.py +74 -0
- model_analyzer/record/types/perf_latency_p90.py +60 -0
- model_analyzer/record/types/perf_latency_p95.py +60 -0
- model_analyzer/record/types/perf_latency_p99.py +60 -0
- model_analyzer/record/types/perf_server_compute_infer.py +97 -0
- model_analyzer/record/types/perf_server_compute_input.py +97 -0
- model_analyzer/record/types/perf_server_compute_output.py +97 -0
- model_analyzer/record/types/perf_server_queue.py +97 -0
- model_analyzer/record/types/perf_throughput.py +105 -0
- model_analyzer/record/types/time_to_first_token_avg.py +60 -0
- model_analyzer/record/types/time_to_first_token_base.py +74 -0
- model_analyzer/record/types/time_to_first_token_max.py +60 -0
- model_analyzer/record/types/time_to_first_token_min.py +60 -0
- model_analyzer/record/types/time_to_first_token_p25.py +60 -0
- model_analyzer/record/types/time_to_first_token_p50.py +60 -0
- model_analyzer/record/types/time_to_first_token_p75.py +60 -0
- model_analyzer/record/types/time_to_first_token_p90.py +60 -0
- model_analyzer/record/types/time_to_first_token_p95.py +60 -0
- model_analyzer/record/types/time_to_first_token_p99.py +60 -0
- model_analyzer/reports/__init__.py +15 -0
- model_analyzer/reports/html_report.py +195 -0
- model_analyzer/reports/pdf_report.py +50 -0
- model_analyzer/reports/report.py +86 -0
- model_analyzer/reports/report_factory.py +62 -0
- model_analyzer/reports/report_manager.py +1376 -0
- model_analyzer/reports/report_utils.py +42 -0
- model_analyzer/result/__init__.py +15 -0
- model_analyzer/result/constraint_manager.py +150 -0
- model_analyzer/result/model_config_measurement.py +354 -0
- model_analyzer/result/model_constraints.py +105 -0
- model_analyzer/result/parameter_search.py +246 -0
- model_analyzer/result/result_manager.py +430 -0
- model_analyzer/result/result_statistics.py +159 -0
- model_analyzer/result/result_table.py +217 -0
- model_analyzer/result/result_table_manager.py +646 -0
- model_analyzer/result/result_utils.py +42 -0
- model_analyzer/result/results.py +277 -0
- model_analyzer/result/run_config_measurement.py +658 -0
- model_analyzer/result/run_config_result.py +210 -0
- model_analyzer/result/run_config_result_comparator.py +110 -0
- model_analyzer/result/sorted_results.py +151 -0
- model_analyzer/state/__init__.py +15 -0
- model_analyzer/state/analyzer_state.py +76 -0
- model_analyzer/state/analyzer_state_manager.py +215 -0
- model_analyzer/triton/__init__.py +15 -0
- model_analyzer/triton/client/__init__.py +15 -0
- model_analyzer/triton/client/client.py +234 -0
- model_analyzer/triton/client/client_factory.py +57 -0
- model_analyzer/triton/client/grpc_client.py +104 -0
- model_analyzer/triton/client/http_client.py +107 -0
- model_analyzer/triton/model/__init__.py +15 -0
- model_analyzer/triton/model/model_config.py +556 -0
- model_analyzer/triton/model/model_config_variant.py +29 -0
- model_analyzer/triton/server/__init__.py +15 -0
- model_analyzer/triton/server/server.py +76 -0
- model_analyzer/triton/server/server_config.py +269 -0
- model_analyzer/triton/server/server_docker.py +229 -0
- model_analyzer/triton/server/server_factory.py +306 -0
- model_analyzer/triton/server/server_local.py +158 -0
- triton_model_analyzer-1.48.0.dist-info/METADATA +52 -0
- triton_model_analyzer-1.48.0.dist-info/RECORD +204 -0
- triton_model_analyzer-1.48.0.dist-info/WHEEL +5 -0
- triton_model_analyzer-1.48.0.dist-info/entry_points.txt +2 -0
- triton_model_analyzer-1.48.0.dist-info/licenses/LICENSE +67 -0
- triton_model_analyzer-1.48.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# Copyright 2021-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
from copy import deepcopy
|
|
18
|
+
|
|
19
|
+
from model_analyzer.constants import CONFIG_PARSER_FAILURE
|
|
20
|
+
|
|
21
|
+
from .config_status import ConfigStatus
|
|
22
|
+
from .config_value import ConfigValue
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ConfigObject(ConfigValue):
|
|
26
|
+
"""
|
|
27
|
+
Representation of dictionaries in Config
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
schema,
|
|
33
|
+
preprocess=None,
|
|
34
|
+
required=False,
|
|
35
|
+
validator=None,
|
|
36
|
+
output_mapper=None,
|
|
37
|
+
name=None,
|
|
38
|
+
):
|
|
39
|
+
"""
|
|
40
|
+
schema : dict
|
|
41
|
+
A dictionary where the keys are the object keys and the values
|
|
42
|
+
are of type ConfigValue
|
|
43
|
+
preprocess : callable
|
|
44
|
+
Function be called before setting new values.
|
|
45
|
+
required : bool
|
|
46
|
+
Whether a given config is required or not.
|
|
47
|
+
validator : callable or None
|
|
48
|
+
A validator for the value of the field.
|
|
49
|
+
output_mapper: callable or None
|
|
50
|
+
This callable unifies the output value of this field.
|
|
51
|
+
name : str
|
|
52
|
+
Fully qualified name for this field.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
super().__init__(preprocess, required, validator, output_mapper, name)
|
|
56
|
+
self._type = self
|
|
57
|
+
self._cli_type = str
|
|
58
|
+
self._value = {}
|
|
59
|
+
self._schema = schema
|
|
60
|
+
|
|
61
|
+
def set_value(self, value):
|
|
62
|
+
"""
|
|
63
|
+
Set the value for this field.
|
|
64
|
+
|
|
65
|
+
Note: Because ConfigObjects can have nested
|
|
66
|
+
ConfigValues and the schema contains these,
|
|
67
|
+
this function performs deep copies of the
|
|
68
|
+
types of objects, and then sets their values.
|
|
69
|
+
|
|
70
|
+
Parameters
|
|
71
|
+
----------
|
|
72
|
+
value : dict
|
|
73
|
+
The value for this field.
|
|
74
|
+
|
|
75
|
+
Returns
|
|
76
|
+
-------
|
|
77
|
+
int
|
|
78
|
+
1 on success, and 0 on failure
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
new_value = {}
|
|
82
|
+
schema = self._schema
|
|
83
|
+
|
|
84
|
+
if type(value) is dict:
|
|
85
|
+
for key, value_ in value.items():
|
|
86
|
+
if key in schema:
|
|
87
|
+
new_item = deepcopy(schema[key])
|
|
88
|
+
|
|
89
|
+
# If the key is not available in the schema, but wildcard is
|
|
90
|
+
# present, we use the schema for the wildcard.
|
|
91
|
+
elif "*" in schema:
|
|
92
|
+
new_item = deepcopy(schema["*"])
|
|
93
|
+
else:
|
|
94
|
+
return ConfigStatus(
|
|
95
|
+
CONFIG_PARSER_FAILURE,
|
|
96
|
+
f'Key "{key}" should not be '
|
|
97
|
+
f'specified in field "{self.name()}".',
|
|
98
|
+
self,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
new_item.set_name(f"{self.name()}.{key}")
|
|
102
|
+
new_value[key] = new_item
|
|
103
|
+
|
|
104
|
+
# If it was not able to set the value, for this
|
|
105
|
+
# field, we fail.
|
|
106
|
+
config_status = new_item.set_value(value_)
|
|
107
|
+
if config_status.status() == CONFIG_PARSER_FAILURE:
|
|
108
|
+
return config_status
|
|
109
|
+
else:
|
|
110
|
+
return ConfigStatus(
|
|
111
|
+
CONFIG_PARSER_FAILURE,
|
|
112
|
+
f'Value for field "{self.name()}" should be an object.'
|
|
113
|
+
f" Type {type(value)} is provided instead.",
|
|
114
|
+
self,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
return super().set_value(new_value)
|
|
118
|
+
|
|
119
|
+
def __getattr__(self, name):
|
|
120
|
+
# We need to add this check, to prevent infinite
|
|
121
|
+
# recursion when using deep copy. See the link below:
|
|
122
|
+
# https://stackoverflow.com/questions/47299243/recursionerror-when-python-copy-deepcopy
|
|
123
|
+
|
|
124
|
+
if name == "__setstate__":
|
|
125
|
+
raise AttributeError(name)
|
|
126
|
+
elif name in self._value:
|
|
127
|
+
return self._value[name].value()
|
|
128
|
+
else:
|
|
129
|
+
raise AttributeError(name)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# Copyright 2021-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
from model_analyzer.constants import CONFIG_PARSER_FAILURE
|
|
18
|
+
|
|
19
|
+
from .config_status import ConfigStatus
|
|
20
|
+
from .config_value import ConfigValue
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ConfigPrimitive(ConfigValue):
|
|
24
|
+
"""
|
|
25
|
+
A wrapper class for the primitive datatypes.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
type_,
|
|
31
|
+
preprocess=None,
|
|
32
|
+
required=False,
|
|
33
|
+
validator=None,
|
|
34
|
+
output_mapper=None,
|
|
35
|
+
name=None,
|
|
36
|
+
):
|
|
37
|
+
"""
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
type_ : type
|
|
41
|
+
Type of the field.
|
|
42
|
+
preprocess : callable
|
|
43
|
+
Function be called before setting new values.
|
|
44
|
+
required : bool
|
|
45
|
+
Whether a given config is required or not.
|
|
46
|
+
validator : callable or None
|
|
47
|
+
A validator for the value of the field.
|
|
48
|
+
output_mapper: callable or None
|
|
49
|
+
This callable unifies the output value of this field.
|
|
50
|
+
name : str
|
|
51
|
+
Fully qualified name for this field.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
super().__init__(preprocess, required, validator, output_mapper, name)
|
|
55
|
+
|
|
56
|
+
self._type = self._cli_type = type_
|
|
57
|
+
self._value = None
|
|
58
|
+
|
|
59
|
+
def set_value(self, value):
|
|
60
|
+
"""
|
|
61
|
+
Set the value for this field.
|
|
62
|
+
|
|
63
|
+
value : object
|
|
64
|
+
The value for this field.
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
if self._is_primitive(value):
|
|
68
|
+
try:
|
|
69
|
+
value = self._type(value)
|
|
70
|
+
except ValueError as e:
|
|
71
|
+
message = (
|
|
72
|
+
f'Failed to set the value for field "{self.name()}". Error: {e}.'
|
|
73
|
+
)
|
|
74
|
+
return ConfigStatus(CONFIG_PARSER_FAILURE, message, self)
|
|
75
|
+
return super().set_value(value)
|
|
76
|
+
else:
|
|
77
|
+
return ConfigStatus(
|
|
78
|
+
CONFIG_PARSER_FAILURE,
|
|
79
|
+
f'Value "{value}" for field "{self.name()}" should be a primitive type.',
|
|
80
|
+
self,
|
|
81
|
+
)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# Copyright 2021-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ConfigStatus:
|
|
19
|
+
def __init__(self, status, message=None, config_object=None):
|
|
20
|
+
"""
|
|
21
|
+
Create a new ConfigStatus
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
status : int
|
|
26
|
+
Status of the config parsing. Accepted
|
|
27
|
+
values are CONFIG_PARSER_SUCCESS and
|
|
28
|
+
CONFIG_PARSER_FAILURE.
|
|
29
|
+
|
|
30
|
+
message : str
|
|
31
|
+
A string message containing the description.
|
|
32
|
+
|
|
33
|
+
config_object : ConfigValue
|
|
34
|
+
ConfigObject that is creating this status.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
self._status = status
|
|
38
|
+
self._message = message
|
|
39
|
+
self._config_object = config_object
|
|
40
|
+
|
|
41
|
+
def status(self):
|
|
42
|
+
"""
|
|
43
|
+
Get the config status.
|
|
44
|
+
|
|
45
|
+
Returns
|
|
46
|
+
-------
|
|
47
|
+
int
|
|
48
|
+
Config status
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
return self._status
|
|
52
|
+
|
|
53
|
+
def message(self):
|
|
54
|
+
"""
|
|
55
|
+
Get the message.
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
str
|
|
60
|
+
The message for the status.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
return self._message
|
|
64
|
+
|
|
65
|
+
def config_object(self):
|
|
66
|
+
"""
|
|
67
|
+
Get the config object for this status.
|
|
68
|
+
|
|
69
|
+
Returns
|
|
70
|
+
-------
|
|
71
|
+
ConfigValue or None
|
|
72
|
+
Config object that created this status.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
return self._config_object
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# Copyright 2021-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
from model_analyzer.constants import CONFIG_PARSER_FAILURE, CONFIG_PARSER_SUCCESS
|
|
18
|
+
|
|
19
|
+
from .config_list_generic import ConfigListGeneric
|
|
20
|
+
from .config_status import ConfigStatus
|
|
21
|
+
from .config_value import ConfigValue
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ConfigSweep(ConfigValue):
|
|
25
|
+
"""
|
|
26
|
+
Representation of dictionaries in Config
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(
|
|
30
|
+
self,
|
|
31
|
+
sweep_type,
|
|
32
|
+
preprocess=None,
|
|
33
|
+
required=False,
|
|
34
|
+
validator=None,
|
|
35
|
+
output_mapper=None,
|
|
36
|
+
):
|
|
37
|
+
"""
|
|
38
|
+
sweep_type : ConfigValue
|
|
39
|
+
The type of parameter that we are going to sweep on.
|
|
40
|
+
preprocess : callable
|
|
41
|
+
Function be called before setting new values.
|
|
42
|
+
required : bool
|
|
43
|
+
Whether a given config is required or not.
|
|
44
|
+
validator : callable or None
|
|
45
|
+
A validator for the value of the field.
|
|
46
|
+
output_mapper: callable or None
|
|
47
|
+
This callable unifies the output value of this field.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
self._sweep_type = sweep_type
|
|
51
|
+
super().__init__(preprocess, required, validator, output_mapper)
|
|
52
|
+
|
|
53
|
+
def set_value(self, value):
|
|
54
|
+
config_statuses = []
|
|
55
|
+
|
|
56
|
+
sweep_type = self._sweep_type
|
|
57
|
+
sweep_type.set_name(self._name)
|
|
58
|
+
config_status = sweep_type.set_value(value)
|
|
59
|
+
config_statuses.append(config_status)
|
|
60
|
+
|
|
61
|
+
if config_status.status() == CONFIG_PARSER_SUCCESS:
|
|
62
|
+
self._is_sweepable = False
|
|
63
|
+
return super().set_value([sweep_type])
|
|
64
|
+
else:
|
|
65
|
+
config_list = ConfigListGeneric(sweep_type)
|
|
66
|
+
config_list.set_name(self._name)
|
|
67
|
+
config_status_list = config_list.set_value(value)
|
|
68
|
+
if config_status_list.status() == CONFIG_PARSER_SUCCESS:
|
|
69
|
+
self._is_sweepable = True
|
|
70
|
+
return super().set_value(config_list)
|
|
71
|
+
config_statuses.append(config_status_list)
|
|
72
|
+
|
|
73
|
+
message = (
|
|
74
|
+
f'Field "{self._name}" is a sweep parameter. If you intend to provide a sweep parameter, '
|
|
75
|
+
"fix the number one error, otherwise fix error number two: "
|
|
76
|
+
f"1. {config_statuses[0].message()}"
|
|
77
|
+
f" 2. {config_statuses[1].message()}"
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
return ConfigStatus(CONFIG_PARSER_FAILURE, message)
|
|
81
|
+
|
|
82
|
+
def is_sweepable(self):
|
|
83
|
+
return self._is_sweepable
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# Copyright 2021-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
from model_analyzer.constants import CONFIG_PARSER_FAILURE, CONFIG_PARSER_SUCCESS
|
|
18
|
+
|
|
19
|
+
from .config_status import ConfigStatus
|
|
20
|
+
from .config_value import ConfigValue
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ConfigUnion(ConfigValue):
|
|
24
|
+
"""
|
|
25
|
+
ConfigUnion allows the value to be any of multiple ConfigValue types.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
types,
|
|
31
|
+
preprocess=None,
|
|
32
|
+
required=False,
|
|
33
|
+
validator=None,
|
|
34
|
+
output_mapper=None,
|
|
35
|
+
name=None,
|
|
36
|
+
):
|
|
37
|
+
"""
|
|
38
|
+
Create a new ConfigUnion.
|
|
39
|
+
|
|
40
|
+
Parameters
|
|
41
|
+
----------
|
|
42
|
+
types : list
|
|
43
|
+
A list of ConfigValue that are allowed for this field.
|
|
44
|
+
preprocess : callable
|
|
45
|
+
Function be called before setting new values.
|
|
46
|
+
required : bool
|
|
47
|
+
Whether a given config is required or not.
|
|
48
|
+
validator : callable or None
|
|
49
|
+
A validator for the final value of the field.
|
|
50
|
+
output_mapper: callable or None
|
|
51
|
+
This callable unifies the output value of this field.
|
|
52
|
+
name : str
|
|
53
|
+
Fully qualified name for this field.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
self._types = types
|
|
57
|
+
self._used_type_index = 0
|
|
58
|
+
super().__init__(preprocess, required, validator, output_mapper, name)
|
|
59
|
+
|
|
60
|
+
def set_value(self, value):
|
|
61
|
+
"""
|
|
62
|
+
Set the value for this field.
|
|
63
|
+
|
|
64
|
+
value : object
|
|
65
|
+
The value for this field.
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
config_statuses = []
|
|
69
|
+
for i, type_ in enumerate(self._types):
|
|
70
|
+
config_status = type_.set_value(value)
|
|
71
|
+
config_statuses.append(config_status)
|
|
72
|
+
if config_status.status() == CONFIG_PARSER_SUCCESS:
|
|
73
|
+
self._used_type_index = i
|
|
74
|
+
return super().set_value(type_)
|
|
75
|
+
|
|
76
|
+
message = (
|
|
77
|
+
f'Value "{value}" cannot be set for field "{self.name()}".'
|
|
78
|
+
" This field allows multiple types of values."
|
|
79
|
+
" You only need to fix one of the errors below:\n"
|
|
80
|
+
)
|
|
81
|
+
for config_status in config_statuses:
|
|
82
|
+
message_lines = config_status.message().split("\n")
|
|
83
|
+
|
|
84
|
+
# ConfigUnion needs to repeat the same structure. The lines
|
|
85
|
+
# below make a couple of adjustments to ensure that
|
|
86
|
+
# lines are printed correctly.
|
|
87
|
+
if type(config_status.config_object()) is ConfigUnion:
|
|
88
|
+
# Make sure that the line is not empty
|
|
89
|
+
if not message_lines[0].strip() == "":
|
|
90
|
+
message += f"\t* {message_lines[0]}\n"
|
|
91
|
+
for message_line in message_lines[1:]:
|
|
92
|
+
message += f"\t {message_line}\n"
|
|
93
|
+
else:
|
|
94
|
+
for message_line in message_lines:
|
|
95
|
+
message += f"\t* {message_line} \n"
|
|
96
|
+
|
|
97
|
+
return ConfigStatus(CONFIG_PARSER_FAILURE, message, self)
|
|
98
|
+
|
|
99
|
+
def set_name(self, name):
|
|
100
|
+
"""
|
|
101
|
+
This function must be called before the set_value.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
super().set_name(name)
|
|
105
|
+
for type_ in self._types:
|
|
106
|
+
type_.set_name(self.name())
|
|
107
|
+
|
|
108
|
+
def cli_type(self):
|
|
109
|
+
used_type_index = self._used_type_index
|
|
110
|
+
return self._types[used_type_index].cli_type()
|
|
111
|
+
|
|
112
|
+
def container_type(self):
|
|
113
|
+
return self.cli_type()
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# Copyright 2021-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
import os
|
|
18
|
+
import shutil
|
|
19
|
+
|
|
20
|
+
from model_analyzer.constants import CONFIG_PARSER_FAILURE, CONFIG_PARSER_SUCCESS
|
|
21
|
+
|
|
22
|
+
from .config_primitive import ConfigPrimitive
|
|
23
|
+
from .config_status import ConfigStatus
|
|
24
|
+
|
|
25
|
+
##############
|
|
26
|
+
# Validators #
|
|
27
|
+
##############
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def parent_path_validator(path):
|
|
31
|
+
"""
|
|
32
|
+
Perform a check on parent directory. Used when the file at
|
|
33
|
+
'path' can be created by Model Analyzer in order to validate
|
|
34
|
+
the parent directory of the file.
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
----------
|
|
38
|
+
path: str
|
|
39
|
+
Absolute path to a file or directory
|
|
40
|
+
|
|
41
|
+
Returns
|
|
42
|
+
-------
|
|
43
|
+
ConfigStatus
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
abspath = os.path.abspath(path)
|
|
47
|
+
|
|
48
|
+
if os.path.exists(os.path.dirname(abspath)):
|
|
49
|
+
return ConfigStatus(status=CONFIG_PARSER_SUCCESS)
|
|
50
|
+
else:
|
|
51
|
+
return ConfigStatus(
|
|
52
|
+
status=CONFIG_PARSER_FAILURE,
|
|
53
|
+
message=f"Either the parent directory for '{path}' does not exist, or Model Analyzer "
|
|
54
|
+
"does not have permissions to execute os.stat on this path.",
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def binary_path_validator(path):
|
|
59
|
+
"""
|
|
60
|
+
Used when path must refer to a valid binary
|
|
61
|
+
such as for tritonserver or perf_analyzer.
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
path: str
|
|
66
|
+
name of a binary if on PATH, or
|
|
67
|
+
absolute path to a binary.
|
|
68
|
+
|
|
69
|
+
Returns
|
|
70
|
+
-------
|
|
71
|
+
ConfigStatus
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
if shutil.which(path):
|
|
75
|
+
return ConfigStatus(status=CONFIG_PARSER_SUCCESS)
|
|
76
|
+
else:
|
|
77
|
+
return ConfigStatus(
|
|
78
|
+
status=CONFIG_PARSER_FAILURE,
|
|
79
|
+
message=f"Either the binary '{path}' is not on the PATH, or Model Analyzer does "
|
|
80
|
+
"not have permissions to execute os.stat on this path.",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def file_path_validator(path):
|
|
85
|
+
"""
|
|
86
|
+
Perform some basic checks on strings passed in as paths.
|
|
87
|
+
Used when the path is expected to exist, and Model Analyzer
|
|
88
|
+
does not create the file at that path.
|
|
89
|
+
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
path: str
|
|
93
|
+
Absolute path to a file or directory
|
|
94
|
+
|
|
95
|
+
Returns
|
|
96
|
+
-------
|
|
97
|
+
ConfigStatus
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
abspath = os.path.abspath(path)
|
|
101
|
+
|
|
102
|
+
if os.path.exists(abspath):
|
|
103
|
+
return ConfigStatus(status=CONFIG_PARSER_SUCCESS)
|
|
104
|
+
else:
|
|
105
|
+
return ConfigStatus(
|
|
106
|
+
status=CONFIG_PARSER_FAILURE,
|
|
107
|
+
message=f"Either '{path}' is a nonexistent path, or Model Analyzer does "
|
|
108
|
+
"not have permissions to execute os.stat on this path",
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
##################
|
|
113
|
+
# Output mappers #
|
|
114
|
+
##################
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def objective_list_output_mapper(objectives):
|
|
118
|
+
"""
|
|
119
|
+
Takes a list of objectives and maps them
|
|
120
|
+
into a dict
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
output_dict = {}
|
|
124
|
+
for objective in objectives:
|
|
125
|
+
value = ConfigPrimitive(type_=int)
|
|
126
|
+
value.set_value(10)
|
|
127
|
+
output_dict[objective] = value
|
|
128
|
+
return output_dict
|