profiler.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. # copyright (c) 2021 PaddlePaddle Authors. All Rights Reserve.
  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. import sys
  15. import paddle.profiler as profiler
  16. # A global variable to record the number of calling times for profiler
  17. # functions. It is used to specify the tracing range of training steps.
  18. _profiler_step_id = 0
  19. # A global variable to avoid parsing from string every time.
  20. _profiler_options = None
  21. _prof = None
  22. class ProfilerOptions(object):
  23. """
  24. Use a string to initialize a ProfilerOptions.
  25. The string should be in the format: "key1=value1;key2=value;key3=value3".
  26. For example:
  27. "profile_path=model.profile"
  28. "batch_range=[50, 60]; profile_path=model.profile"
  29. "batch_range=[50, 60]; tracer_option=OpDetail; profile_path=model.profile"
  30. ProfilerOptions supports following key-value pair:
  31. batch_range - a integer list, e.g. [100, 110].
  32. state - a string, the optional values are 'CPU', 'GPU' or 'All'.
  33. sorted_key - a string, the optional values are 'calls', 'total',
  34. 'max', 'min' or 'ave.
  35. tracer_option - a string, the optional values are 'Default', 'OpDetail',
  36. 'AllOpDetail'.
  37. profile_path - a string, the path to save the serialized profile data,
  38. which can be used to generate a timeline.
  39. exit_on_finished - a boolean.
  40. """
  41. def __init__(self, options_str):
  42. assert isinstance(options_str, str)
  43. self._options = {
  44. "batch_range": [10, 20],
  45. "state": "All",
  46. "sorted_key": "total",
  47. "tracer_option": "Default",
  48. "profile_path": "/tmp/profile",
  49. "exit_on_finished": True,
  50. "timer_only": True,
  51. }
  52. self._parse_from_string(options_str)
  53. def _parse_from_string(self, options_str):
  54. for kv in options_str.replace(" ", "").split(";"):
  55. key, value = kv.split("=")
  56. if key == "batch_range":
  57. value_list = value.replace("[", "").replace("]", "").split(",")
  58. value_list = list(map(int, value_list))
  59. if (
  60. len(value_list) >= 2
  61. and value_list[0] >= 0
  62. and value_list[1] > value_list[0]
  63. ):
  64. self._options[key] = value_list
  65. elif key == "exit_on_finished":
  66. self._options[key] = value.lower() in ("yes", "true", "t", "1")
  67. elif key in ["state", "sorted_key", "tracer_option", "profile_path"]:
  68. self._options[key] = value
  69. elif key == "timer_only":
  70. self._options[key] = value
  71. def __getitem__(self, name):
  72. if self._options.get(name, None) is None:
  73. raise ValueError("ProfilerOptions does not have an option named %s." % name)
  74. return self._options[name]
  75. def add_profiler_step(options_str=None):
  76. """
  77. Enable the operator-level timing using PaddlePaddle's profiler.
  78. The profiler uses a independent variable to count the profiler steps.
  79. One call of this function is treated as a profiler step.
  80. Args:
  81. profiler_options - a string to initialize the ProfilerOptions.
  82. Default is None, and the profiler is disabled.
  83. """
  84. if options_str is None:
  85. return
  86. global _prof
  87. global _profiler_step_id
  88. global _profiler_options
  89. if _profiler_options is None:
  90. _profiler_options = ProfilerOptions(options_str)
  91. # profile : https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/performance_improving/profiling_model.html#chakanxingnengshujudetongjibiaodan
  92. # timer_only = True only the model's throughput and time overhead are displayed
  93. # timer_only = False calling summary can print a statistical form that presents performance data from different perspectives.
  94. # timer_only = False the output Timeline information can be found in the profiler_log directory
  95. if _prof is None:
  96. _timer_only = str(_profiler_options["timer_only"]) == str(True)
  97. _prof = profiler.Profiler(
  98. scheduler=(
  99. _profiler_options["batch_range"][0],
  100. _profiler_options["batch_range"][1],
  101. ),
  102. on_trace_ready=profiler.export_chrome_tracing("./profiler_log"),
  103. timer_only=_timer_only,
  104. )
  105. _prof.start()
  106. else:
  107. _prof.step()
  108. if _profiler_step_id == _profiler_options["batch_range"][1]:
  109. _prof.stop()
  110. _prof.summary(op_detail=True, thread_sep=False, time_unit="ms")
  111. _prof = None
  112. if _profiler_options["exit_on_finished"]:
  113. sys.exit(0)
  114. _profiler_step_id += 1