You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

memory_usage_analyser.py 5.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. # Copyright 2021 Huawei Technologies Co., Ltd
  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. """The memory analyser."""
  16. from enum import Enum
  17. import json
  18. import os
  19. from mindinsight.profiler.analyser.base_analyser import BaseAnalyser
  20. from mindinsight.profiler.common.exceptions.exceptions import ProfilerIOException, \
  21. ProfilerFileNotFoundException
  22. from mindinsight.profiler.common.log import logger
  23. from mindinsight.profiler.common.validator.validate_path import validate_and_normalize_path
  24. from mindinsight.utils.exceptions import ParamValueError
  25. class FileType(Enum):
  26. """The enum of memory usage file types."""
  27. SUMMARY = 'summary'
  28. DETAILS = 'details'
  29. class MemoryUsageAnalyser(BaseAnalyser):
  30. """Analyse memory usage data from file."""
  31. _summary_filename = 'memory_usage_summary_{}.json'
  32. _details_filename = 'memory_usage_details_{}.json'
  33. def _load(self):
  34. """Load data according to the parsed profiling files."""
  35. def _filter(self, filter_condition):
  36. """
  37. Filter the profiling data according to the filter condition.
  38. Args:
  39. filter_condition (dict): The filter condition.
  40. """
  41. def get_memory_usage_summary(self, device_type):
  42. """
  43. Get memory usage summary data for UI display.
  44. Args:
  45. device_type (str): Device type, e.g., GPU, Ascend.
  46. Returns:
  47. json, the content of memory usage summary.
  48. """
  49. summary = self._get_file_content(device_type, FileType.SUMMARY.value)
  50. memory_summary = {'summary': summary}
  51. return memory_summary
  52. def get_memory_usage_graphics(self, device_type):
  53. """
  54. Get memory usage data for UI display.
  55. Args:
  56. device_type (str): Device type, e.g., GPU, Ascend.
  57. Returns:
  58. json, the content of memory usage data.
  59. """
  60. memory_details = self._get_file_content(device_type, FileType.DETAILS.value)
  61. for graph_id in memory_details.keys():
  62. if 'breakdowns' in memory_details[graph_id]:
  63. memory_details[graph_id].pop('breakdowns')
  64. return memory_details
  65. def get_memory_usage_breakdowns(self, device_type, graph_id, node_id):
  66. """
  67. Get memory usage breakdowns for each node.
  68. Args:
  69. device_type (str): Device type, e.g., GPU, Ascend.
  70. graph_id (int): Graph id.
  71. node_id (int): Node id.
  72. Returns:
  73. json, the content of memory usage breakdowns.
  74. """
  75. memory_details = self._get_file_content(device_type, FileType.DETAILS.value)
  76. if graph_id not in memory_details:
  77. logger.error('Invalid graph id: %s', graph_id)
  78. raise ParamValueError('Invalid graph id.')
  79. graph = memory_details[graph_id]
  80. if not ('breakdowns' in graph and node_id < len(graph['breakdowns'])):
  81. logger.error('Invalid node id: %s', node_id)
  82. raise ParamValueError('Invalid node id.')
  83. memory_breakdowns = graph.get('breakdowns')[node_id]
  84. return {'breakdowns': memory_breakdowns}
  85. def _get_file_content(self, device_type, file_type):
  86. """
  87. Get file content for different types of memory usage files.
  88. Args:
  89. device_type (str): Device type, e.g., GPU, Ascend.
  90. file_type (str): memory usage file type, e.g., summary, details.
  91. Returns:
  92. dict, file content corresponding to file_type.
  93. """
  94. file_path = self._get_file_path(device_type, file_type)
  95. if not os.path.exists(file_path):
  96. logger.error('Invalid file path. Please check the output path: %s', file_path)
  97. raise ProfilerFileNotFoundException(msg='Invalid memory file path.')
  98. try:
  99. with open(file_path, 'r') as f_obj:
  100. file_content = json.load(f_obj)
  101. except (IOError, OSError, json.JSONDecodeError) as err:
  102. logger.error('Error occurred when read memory file: %s', err)
  103. raise ProfilerIOException()
  104. return file_content
  105. def _get_file_path(self, device_type, file_type):
  106. """
  107. Get memory usage summary file.
  108. Args:
  109. device_type (str): Device type, e.g., GPU, Ascend.
  110. file_type (str): memory usage file type, e.g., summary, details.
  111. Returns:
  112. str, file path of memory usage file corresponding to its file_type.
  113. """
  114. filename = ""
  115. if device_type == "ascend":
  116. if file_type is FileType.SUMMARY.value:
  117. filename = self._summary_filename.format(self._device_id)
  118. elif file_type is FileType.DETAILS.value:
  119. filename = self._details_filename.format(self._device_id)
  120. else:
  121. logger.error('Memory Usage only supports Ascend for now. Please check the device type.')
  122. raise ParamValueError("Invalid device type.")
  123. file_path = os.path.join(self._profiling_dir, filename)
  124. file_path = validate_and_normalize_path(
  125. file_path, raise_key='Invalid memory usage file path.'
  126. )
  127. return file_path