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,141 @@
|
|
|
1
|
+
# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
import model_analyzer.monitor.dcgm.pydcgm as pydcgm
|
|
16
|
+
import model_analyzer.monitor.dcgm.dcgm_structs as dcgm_structs
|
|
17
|
+
import model_analyzer.monitor.dcgm.dcgm_agent as dcgm_agent
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class DcgmHandle:
|
|
21
|
+
'''
|
|
22
|
+
Class to encapsulate a handle to DCGM and global methods to control + query the host engine
|
|
23
|
+
'''
|
|
24
|
+
|
|
25
|
+
def __init__(self,
|
|
26
|
+
handle=None,
|
|
27
|
+
ipAddress=None,
|
|
28
|
+
opMode=dcgm_structs.DCGM_OPERATION_MODE_AUTO,
|
|
29
|
+
persistAfterDisconnect=False,
|
|
30
|
+
unixSocketPath=None,
|
|
31
|
+
timeoutMs=0):
|
|
32
|
+
'''
|
|
33
|
+
Constructor
|
|
34
|
+
|
|
35
|
+
handle is an existing handle from dcgmInit(). Pass None if you want this object to handle DCGM initialization for you
|
|
36
|
+
ipAddress is the host to connect to. None = start embedded host engine
|
|
37
|
+
opMode is a dcgm_structs.DCGM_OPERATION_MODE_* constant for how the host engine should run (embedded mode only)
|
|
38
|
+
persistAfterDisconnect (TCP-IP connections only) is whether the host engine should persist all of our watches
|
|
39
|
+
after we disconnect. 1=persist our watches. 0=clean up after our connection
|
|
40
|
+
unixSocketPath is a path to a path on the local filesystem that is a unix socket that the host engine is listening on.
|
|
41
|
+
This option is mutually exclusive with ipAddress
|
|
42
|
+
timeoutMs is how long to wait for TCP/IP or Unix domain connections to establish in ms. 0=Default timeout (5000ms)
|
|
43
|
+
'''
|
|
44
|
+
self._handleCreated = False
|
|
45
|
+
self._persistAfterDisconnect = persistAfterDisconnect
|
|
46
|
+
|
|
47
|
+
if handle is not None:
|
|
48
|
+
self.handle = handle
|
|
49
|
+
return
|
|
50
|
+
|
|
51
|
+
self._ipAddress = ipAddress
|
|
52
|
+
|
|
53
|
+
#Can't provide both unix socket and ip address
|
|
54
|
+
if ipAddress is not None and unixSocketPath is not None:
|
|
55
|
+
raise dcgm_structs.dcgmExceptionClass(dcgm_structs.DCGM_ST_BADPARAM)
|
|
56
|
+
|
|
57
|
+
#Initialize the DCGM client library
|
|
58
|
+
dcgm_structs._dcgmInit()
|
|
59
|
+
dcgm_agent.dcgmInit(
|
|
60
|
+
) #Not harmful to call this multiple times in a process
|
|
61
|
+
|
|
62
|
+
#If neither ipAddress nor unixSocketPath are present, start an embedded host engine
|
|
63
|
+
if ipAddress is None and unixSocketPath is None:
|
|
64
|
+
self.handle = dcgm_agent.dcgmStartEmbedded(opMode)
|
|
65
|
+
self.isEmbedded = True
|
|
66
|
+
self._handleCreated = True
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
#Set up connection parameters. We're connecting to something
|
|
70
|
+
connectParams = dcgm_structs.c_dcgmConnectV2Params_v2()
|
|
71
|
+
connectParams.version = dcgm_structs.c_dcgmConnectV2Params_version
|
|
72
|
+
connectParams.timeoutMs = timeoutMs
|
|
73
|
+
if self._persistAfterDisconnect:
|
|
74
|
+
connectParams.persistAfterDisconnect = 1
|
|
75
|
+
else:
|
|
76
|
+
connectParams.persistAfterDisconnect = 0
|
|
77
|
+
|
|
78
|
+
if ipAddress is not None:
|
|
79
|
+
connectToAddress = ipAddress
|
|
80
|
+
connectParams.addressIsUnixSocket = 0
|
|
81
|
+
else:
|
|
82
|
+
connectToAddress = unixSocketPath
|
|
83
|
+
connectParams.addressIsUnixSocket = 1
|
|
84
|
+
|
|
85
|
+
self.handle = dcgm_agent.dcgmConnect_v2(connectToAddress, connectParams)
|
|
86
|
+
self.isEmbedded = False
|
|
87
|
+
self._handleCreated = True
|
|
88
|
+
|
|
89
|
+
def __del__(self):
|
|
90
|
+
'''
|
|
91
|
+
Destructor
|
|
92
|
+
'''
|
|
93
|
+
if self._handleCreated:
|
|
94
|
+
self.Shutdown()
|
|
95
|
+
|
|
96
|
+
def GetSystem(self):
|
|
97
|
+
'''
|
|
98
|
+
Get a DcgmSystem instance for this handle
|
|
99
|
+
'''
|
|
100
|
+
return pydcgm.DcgmSystem(self)
|
|
101
|
+
|
|
102
|
+
def __StopDcgm__(self):
|
|
103
|
+
'''
|
|
104
|
+
Shuts down either the hostengine or the embedded server
|
|
105
|
+
'''
|
|
106
|
+
if self.isEmbedded:
|
|
107
|
+
dcgm_agent.dcgmStopEmbedded(self.handle)
|
|
108
|
+
else:
|
|
109
|
+
dcgm_agent.dcgmDisconnect(self.handle)
|
|
110
|
+
|
|
111
|
+
def Shutdown(self):
|
|
112
|
+
'''
|
|
113
|
+
Shutdown DCGM hostengine
|
|
114
|
+
'''
|
|
115
|
+
if not self._handleCreated:
|
|
116
|
+
return
|
|
117
|
+
|
|
118
|
+
try:
|
|
119
|
+
self.__StopDcgm__()
|
|
120
|
+
except AttributeError as e:
|
|
121
|
+
# Due to multi-threading, sometimes this is called after the modules have been unloaded, making
|
|
122
|
+
# dcgm_agent effectively NoneType and resulting in this error being thrown.
|
|
123
|
+
pass
|
|
124
|
+
|
|
125
|
+
self._handleCreated = False
|
|
126
|
+
self.handle = None
|
|
127
|
+
|
|
128
|
+
@staticmethod
|
|
129
|
+
def Unload():
|
|
130
|
+
'''
|
|
131
|
+
Unload DCGM, removing any memory it is pointing at. Use this if you really
|
|
132
|
+
want DCGM gone from your process. Shutdown() only closes the connection/embedded host engine
|
|
133
|
+
that was create in __init__().
|
|
134
|
+
'''
|
|
135
|
+
dcgm_agent.dcgmShutdown()
|
|
136
|
+
|
|
137
|
+
def GetIpAddress(self):
|
|
138
|
+
'''
|
|
139
|
+
Returns the IP address associated with this handle. None=embedded connection
|
|
140
|
+
'''
|
|
141
|
+
return self._ipAddress
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
from model_analyzer.monitor.dcgm.DcgmReader import DcgmReader
|
|
15
|
+
from json import dumps as toJson
|
|
16
|
+
from os import environ
|
|
17
|
+
from socket import socket, AF_INET, SOCK_DGRAM
|
|
18
|
+
from time import sleep
|
|
19
|
+
import model_analyzer.monitor.dcgm.dcgm_fields as dcgm_fields
|
|
20
|
+
import logging
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class DcgmJsonReader(DcgmReader):
|
|
24
|
+
|
|
25
|
+
###########################################################################
|
|
26
|
+
def ConvertFieldIdToTag(self, fieldId):
|
|
27
|
+
return self.m_fieldIdToInfo[fieldId].tag
|
|
28
|
+
|
|
29
|
+
###########################################################################
|
|
30
|
+
def PrepareJson(self, gpuId, obj):
|
|
31
|
+
'''
|
|
32
|
+
Receive an object with measurements turn it into an equivalent JSON. We
|
|
33
|
+
add the GPU UUID first.
|
|
34
|
+
'''
|
|
35
|
+
uuid = self.m_gpuIdToUUId[gpuId]
|
|
36
|
+
# This mutates the original object, but it shouldn't be a problem here
|
|
37
|
+
obj['gpu_uuid'] = uuid
|
|
38
|
+
return toJson(obj)
|
|
39
|
+
|
|
40
|
+
###########################################################################
|
|
41
|
+
def CustomDataHandler(self, fvs):
|
|
42
|
+
for gpuId in list(fvs.keys()):
|
|
43
|
+
# We don't need the keys because each value has a `fieldId`
|
|
44
|
+
# So just get the values
|
|
45
|
+
gpuData = list(fvs[gpuId].values())
|
|
46
|
+
|
|
47
|
+
# Get the values from FV (which is a list of values)
|
|
48
|
+
valuesListOfLists = [datum.values for datum in gpuData]
|
|
49
|
+
|
|
50
|
+
# We only want the last measurement
|
|
51
|
+
lastValueList = [l[-1] for l in valuesListOfLists]
|
|
52
|
+
|
|
53
|
+
# Turn FV into a conventional Python Object which can be converted to JSON
|
|
54
|
+
outObject = {
|
|
55
|
+
self.ConvertFieldIdToTag(i.fieldId): i.value
|
|
56
|
+
for i in lastValueList
|
|
57
|
+
}
|
|
58
|
+
outJson = self.PrepareJson(gpuId, outObject)
|
|
59
|
+
|
|
60
|
+
self.CustomJsonHandler(outJson)
|
|
61
|
+
|
|
62
|
+
###########################################################################
|
|
63
|
+
def CustomJsonHandler(self, outJson):
|
|
64
|
+
'''
|
|
65
|
+
This method should be overriden by subclasses to handle the JSON objects
|
|
66
|
+
received.
|
|
67
|
+
'''
|
|
68
|
+
logging.warning('CustomJsonHandler has not been overriden')
|
|
69
|
+
logging.info(outJson)
|