|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import sys |
|
import paddle |
|
|
|
|
|
|
|
_profiler_step_id = 0 |
|
|
|
|
|
_profiler_options = 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 |
|
} |
|
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 |
|
|
|
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 _profiler_step_id |
|
global _profiler_options |
|
|
|
if _profiler_options is None: |
|
_profiler_options = ProfilerOptions(options_str) |
|
|
|
if _profiler_step_id == _profiler_options['batch_range'][0]: |
|
paddle.utils.profiler.start_profiler( |
|
_profiler_options['state'], _profiler_options['tracer_option']) |
|
elif _profiler_step_id == _profiler_options['batch_range'][1]: |
|
paddle.utils.profiler.stop_profiler(_profiler_options['sorted_key'], |
|
_profiler_options['profile_path']) |
|
if _profiler_options['exit_on_finished']: |
|
sys.exit(0) |
|
|
|
_profiler_step_id += 1 |
|
|