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,159 @@
|
|
|
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 ResultStatistics:
|
|
19
|
+
"""
|
|
20
|
+
An object containing all statistics relevant
|
|
21
|
+
to an instance of Analyzer
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self):
|
|
25
|
+
self._total_configurations = {}
|
|
26
|
+
self._passing_measurements = {}
|
|
27
|
+
self._failing_measurements = {}
|
|
28
|
+
|
|
29
|
+
def total_configurations(self, model_name):
|
|
30
|
+
"""
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
model_name: str
|
|
34
|
+
The name of the model for which
|
|
35
|
+
we are getting the total number of
|
|
36
|
+
configurations
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
int
|
|
41
|
+
total number of configuration
|
|
42
|
+
searched by the model analyzer
|
|
43
|
+
for a given model.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
return self._total_configurations[model_name]
|
|
47
|
+
|
|
48
|
+
def set_total_configurations(self, model_name, total):
|
|
49
|
+
"""
|
|
50
|
+
Parameters
|
|
51
|
+
----------
|
|
52
|
+
model_name: str
|
|
53
|
+
The name of the model for which
|
|
54
|
+
we are getting the total number of
|
|
55
|
+
configurations
|
|
56
|
+
total : int
|
|
57
|
+
The number of configurations tried for
|
|
58
|
+
this model
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
int
|
|
63
|
+
total number of configuration
|
|
64
|
+
searched by the model analyzer
|
|
65
|
+
for a given model.
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
self._total_configurations[model_name] = total
|
|
69
|
+
|
|
70
|
+
def total_measurements(self, model_name):
|
|
71
|
+
"""
|
|
72
|
+
Parameters
|
|
73
|
+
----------
|
|
74
|
+
model_name: str
|
|
75
|
+
The name of the model for which
|
|
76
|
+
we are getting the total number of
|
|
77
|
+
measurements
|
|
78
|
+
|
|
79
|
+
Returns
|
|
80
|
+
-------
|
|
81
|
+
int
|
|
82
|
+
total number of measurements
|
|
83
|
+
searched by the model analyzer
|
|
84
|
+
for a given model.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
return self.passing_measurements(model_name) + self.failing_measurements(
|
|
88
|
+
model_name
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
def set_passing_measurements(self, model_name, passing):
|
|
92
|
+
"""
|
|
93
|
+
Sets the number of passing configuration
|
|
94
|
+
searched by the model analyzer.
|
|
95
|
+
|
|
96
|
+
Parameters
|
|
97
|
+
----------
|
|
98
|
+
model_name: str
|
|
99
|
+
The name of the model for which
|
|
100
|
+
we are setting the number of passing
|
|
101
|
+
measurements
|
|
102
|
+
passing : int
|
|
103
|
+
The number of passing measurements tried
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
self._passing_measurements[model_name] = passing
|
|
107
|
+
|
|
108
|
+
def passing_measurements(self, model_name):
|
|
109
|
+
"""
|
|
110
|
+
Parameters
|
|
111
|
+
----------
|
|
112
|
+
model_name: str
|
|
113
|
+
The name of the model for which
|
|
114
|
+
we are getting the number of passing
|
|
115
|
+
measurements
|
|
116
|
+
|
|
117
|
+
Returns
|
|
118
|
+
-------
|
|
119
|
+
int
|
|
120
|
+
passing number of measurements
|
|
121
|
+
searched by the model analyzer.
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
return self._passing_measurements[model_name]
|
|
125
|
+
|
|
126
|
+
def set_failing_measurements(self, model_name, failing):
|
|
127
|
+
"""
|
|
128
|
+
Sets the number of failing configuration
|
|
129
|
+
searched by the model analyzer.
|
|
130
|
+
|
|
131
|
+
Parameters
|
|
132
|
+
----------
|
|
133
|
+
model_name: str
|
|
134
|
+
The name of the model for which
|
|
135
|
+
we are setting the number of failing
|
|
136
|
+
measurements
|
|
137
|
+
failing : int
|
|
138
|
+
The total number of configs failing
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
self._failing_measurements[model_name] = failing
|
|
142
|
+
|
|
143
|
+
def failing_measurements(self, model_name):
|
|
144
|
+
"""
|
|
145
|
+
Parameters
|
|
146
|
+
----------
|
|
147
|
+
model_name: str
|
|
148
|
+
The name of the model for which
|
|
149
|
+
we are getting the number of failing
|
|
150
|
+
measurements
|
|
151
|
+
|
|
152
|
+
Returns
|
|
153
|
+
-------
|
|
154
|
+
int
|
|
155
|
+
total number of failing measurements
|
|
156
|
+
searched by the model analyzer.
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
return self._failing_measurements[model_name]
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# Copyright 2020-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 RESULT_TABLE_COLUMN_PADDING
|
|
18
|
+
from model_analyzer.model_analyzer_exceptions import TritonModelAnalyzerException
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ResultTable:
|
|
22
|
+
"""
|
|
23
|
+
A class that implements a generic table interface with headers rows
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
column_padding = RESULT_TABLE_COLUMN_PADDING
|
|
27
|
+
|
|
28
|
+
def __init__(self, headers, title=None):
|
|
29
|
+
"""
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
headers : list of str
|
|
33
|
+
Names of the columns of this table
|
|
34
|
+
title : str
|
|
35
|
+
Title of the table
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
self._headers = headers
|
|
39
|
+
self._title = title
|
|
40
|
+
self._column_widths = [len(header) + self.column_padding for header in headers]
|
|
41
|
+
self._rows = []
|
|
42
|
+
|
|
43
|
+
def title(self):
|
|
44
|
+
"""
|
|
45
|
+
Get table title
|
|
46
|
+
|
|
47
|
+
Returns
|
|
48
|
+
-------
|
|
49
|
+
str
|
|
50
|
+
Title of the table
|
|
51
|
+
"""
|
|
52
|
+
return self._title
|
|
53
|
+
|
|
54
|
+
def headers(self):
|
|
55
|
+
"""
|
|
56
|
+
Returns
|
|
57
|
+
-------
|
|
58
|
+
list of str
|
|
59
|
+
names of the columns of this table
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
return self._headers
|
|
63
|
+
|
|
64
|
+
def size(self):
|
|
65
|
+
"""
|
|
66
|
+
Returns
|
|
67
|
+
-------
|
|
68
|
+
int
|
|
69
|
+
number of rows in this
|
|
70
|
+
table
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
return len(self._rows)
|
|
74
|
+
|
|
75
|
+
def column_widths(self):
|
|
76
|
+
"""
|
|
77
|
+
Returns
|
|
78
|
+
-------
|
|
79
|
+
list of ints
|
|
80
|
+
Current width in spaces of each column in table.
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
return self._column_widths
|
|
84
|
+
|
|
85
|
+
def empty(self):
|
|
86
|
+
"""
|
|
87
|
+
Returns
|
|
88
|
+
-------
|
|
89
|
+
True if this table has no data
|
|
90
|
+
False if it does
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
return len(self._rows) == 0
|
|
94
|
+
|
|
95
|
+
def insert_row_by_index(self, row, index=None):
|
|
96
|
+
"""
|
|
97
|
+
Adds a row to the table. Handles wrapping.
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
row : list
|
|
102
|
+
A row of data to add to the ResultTable
|
|
103
|
+
|
|
104
|
+
Raises
|
|
105
|
+
------
|
|
106
|
+
TritonModelAnalyzerException
|
|
107
|
+
if there is a mismatch between the table headers
|
|
108
|
+
and the row to be inserted.
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
if len(row) != len(self._headers):
|
|
112
|
+
raise TritonModelAnalyzerException(
|
|
113
|
+
f"Inserted row contains {len(row)} values."
|
|
114
|
+
f"There are {len(self._headers)} provided headers."
|
|
115
|
+
)
|
|
116
|
+
if index is None:
|
|
117
|
+
index = len(self._rows)
|
|
118
|
+
self._rows.insert(index, row[:])
|
|
119
|
+
|
|
120
|
+
for i in range(len(row)):
|
|
121
|
+
self._column_widths[i] = max(
|
|
122
|
+
len(str(row[i])) + self.column_padding, self._column_widths[i]
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
def get_row_by_index(self, index):
|
|
126
|
+
"""
|
|
127
|
+
Returns the row at given index
|
|
128
|
+
|
|
129
|
+
Parameters
|
|
130
|
+
----------
|
|
131
|
+
index : int
|
|
132
|
+
index of row to return
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
-------
|
|
136
|
+
list of vals
|
|
137
|
+
The contents of the desired column
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
if index < 0 or index >= len(self._rows):
|
|
141
|
+
raise TritonModelAnalyzerException(
|
|
142
|
+
f"Index {index} out of range for get_row"
|
|
143
|
+
)
|
|
144
|
+
return self._rows[index]
|
|
145
|
+
|
|
146
|
+
def remove_row_by_index(self, index):
|
|
147
|
+
"""
|
|
148
|
+
Removes row at given index
|
|
149
|
+
from the table
|
|
150
|
+
|
|
151
|
+
Parameters
|
|
152
|
+
----------
|
|
153
|
+
index : int
|
|
154
|
+
The index of the row to be removed
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
if len(self._rows) == 0:
|
|
158
|
+
raise TritonModelAnalyzerException(
|
|
159
|
+
"Attempting to remove result from an empty ResultTable!"
|
|
160
|
+
)
|
|
161
|
+
if index < 0 or index >= len(self._rows):
|
|
162
|
+
raise TritonModelAnalyzerException(
|
|
163
|
+
f"Index {index} out of range for remove_row_by_index"
|
|
164
|
+
)
|
|
165
|
+
self._rows.pop(index)
|
|
166
|
+
|
|
167
|
+
def to_formatted_string(self, separator="", ignore_widths=False):
|
|
168
|
+
"""
|
|
169
|
+
Converts the table into its string representation
|
|
170
|
+
making it easy to write by a writer
|
|
171
|
+
|
|
172
|
+
Parameters
|
|
173
|
+
----------
|
|
174
|
+
separator : str
|
|
175
|
+
The string that will separate columns of a row in th
|
|
176
|
+
table
|
|
177
|
+
ignore_widths : bool
|
|
178
|
+
Each cell is as wide as its content. Useful
|
|
179
|
+
for csv format.
|
|
180
|
+
|
|
181
|
+
Returns
|
|
182
|
+
-------
|
|
183
|
+
str
|
|
184
|
+
The formatted table as a string ready for writing
|
|
185
|
+
"""
|
|
186
|
+
|
|
187
|
+
output_rows = []
|
|
188
|
+
for row in [self._headers] + self._rows:
|
|
189
|
+
output_rows.append(self._row_to_string(row, separator, ignore_widths))
|
|
190
|
+
return "\n".join(output_rows)
|
|
191
|
+
|
|
192
|
+
def _row_to_string(self, row, separator, ignore_widths):
|
|
193
|
+
"""
|
|
194
|
+
Converts a single row to its string representation
|
|
195
|
+
"""
|
|
196
|
+
|
|
197
|
+
if ignore_widths:
|
|
198
|
+
return separator.join([str(row[j]) for j in range(len(row))])
|
|
199
|
+
else:
|
|
200
|
+
return separator.join(
|
|
201
|
+
[
|
|
202
|
+
self._pad_or_trunc(str(row[j]), self._column_widths[j])
|
|
203
|
+
for j in range(len(row))
|
|
204
|
+
]
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
def _pad_or_trunc(self, string, length):
|
|
208
|
+
"""
|
|
209
|
+
Constructs a single cell of the table by either padding or truncating
|
|
210
|
+
the value inside
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
diff = length - len(string)
|
|
214
|
+
if diff >= 0:
|
|
215
|
+
return string + (" ") * diff
|
|
216
|
+
else:
|
|
217
|
+
return string[:diff]
|