| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import sys |
| import paddle.profiler as profiler |
|
|
| |
| |
| _profiler_step_id = 0 |
|
|
| |
| _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) |
| |
| |
| |
| |
| 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 |
|
|