File size: 5,246 Bytes
8207382 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | # copyright (c) 2021 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
import paddle.profiler as profiler
# A global variable to record the number of calling times for profiler
# functions. It is used to specify the tracing range of training steps.
_profiler_step_id = 0
# A global variable to avoid parsing from string every time.
_profiler_options = None
_prof = None
class ProfilerOptions(object):
"""
Use a string to initialize a ProfilerOptions.
The string should be in the format: "key1=value1;key2=value;key3=value3".
For example:
"profile_path=model.profile"
"batch_range=[50, 60]; profile_path=model.profile"
"batch_range=[50, 60]; tracer_option=OpDetail; profile_path=model.profile"
ProfilerOptions supports following key-value pair:
batch_range - a integer list, e.g. [100, 110].
state - a string, the optional values are 'CPU', 'GPU' or 'All'.
sorted_key - a string, the optional values are 'calls', 'total',
'max', 'min' or 'ave.
tracer_option - a string, the optional values are 'Default', 'OpDetail',
'AllOpDetail'.
profile_path - a string, the path to save the serialized profile data,
which can be used to generate a timeline.
exit_on_finished - a boolean.
"""
def __init__(self, options_str):
assert isinstance(options_str, str)
self._options = {
"batch_range": [10, 20],
"state": "All",
"sorted_key": "total",
"tracer_option": "Default",
"profile_path": "/tmp/profile",
"exit_on_finished": True,
"timer_only": True,
}
self._parse_from_string(options_str)
def _parse_from_string(self, options_str):
for kv in options_str.replace(" ", "").split(";"):
key, value = kv.split("=")
if key == "batch_range":
value_list = value.replace("[", "").replace("]", "").split(",")
value_list = list(map(int, value_list))
if (
len(value_list) >= 2
and value_list[0] >= 0
and value_list[1] > value_list[0]
):
self._options[key] = value_list
elif key == "exit_on_finished":
self._options[key] = value.lower() in ("yes", "true", "t", "1")
elif key in ["state", "sorted_key", "tracer_option", "profile_path"]:
self._options[key] = value
elif key == "timer_only":
self._options[key] = value
def __getitem__(self, name):
if self._options.get(name, None) is None:
raise ValueError("ProfilerOptions does not have an option named %s." % name)
return self._options[name]
def add_profiler_step(options_str=None):
"""
Enable the operator-level timing using PaddlePaddle's profiler.
The profiler uses a independent variable to count the profiler steps.
One call of this function is treated as a profiler step.
Args:
profiler_options - a string to initialize the ProfilerOptions.
Default is None, and the profiler is disabled.
"""
if options_str is None:
return
global _prof
global _profiler_step_id
global _profiler_options
if _profiler_options is None:
_profiler_options = ProfilerOptions(options_str)
# profile : https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/performance_improving/profiling_model.html#chakanxingnengshujudetongjibiaodan
# timer_only = True only the model's throughput and time overhead are displayed
# timer_only = False calling summary can print a statistical form that presents performance data from different perspectives.
# timer_only = False the output Timeline information can be found in the profiler_log directory
if _prof is None:
_timer_only = str(_profiler_options["timer_only"]) == str(True)
_prof = profiler.Profiler(
scheduler=(
_profiler_options["batch_range"][0],
_profiler_options["batch_range"][1],
),
on_trace_ready=profiler.export_chrome_tracing("./profiler_log"),
timer_only=_timer_only,
)
_prof.start()
else:
_prof.step()
if _profiler_step_id == _profiler_options["batch_range"][1]:
_prof.stop()
_prof.summary(op_detail=True, thread_sep=False, time_unit="ms")
_prof = None
if _profiler_options["exit_on_finished"]:
sys.exit(0)
_profiler_step_id += 1
|