From ab76cfab0233bf4d14d64b503e27b78a4ea22273 Mon Sep 17 00:00:00 2001 From: starmountain1997 Date: Wed, 17 Jul 2024 10:37:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=8D=A2=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../analyzer/overall/overall_analyzer.py | 45 -------------- .../overall/overall_summary_analyzer.py | 62 ++++++++++++------- 2 files changed, 40 insertions(+), 67 deletions(-) delete mode 100644 profiler/advisor/analyzer/overall/overall_analyzer.py diff --git a/profiler/advisor/analyzer/overall/overall_analyzer.py b/profiler/advisor/analyzer/overall/overall_analyzer.py deleted file mode 100644 index 916a396b3d..0000000000 --- a/profiler/advisor/analyzer/overall/overall_analyzer.py +++ /dev/null @@ -1,45 +0,0 @@ -import logging -from typing import Dict, List - -from profiler.advisor.analyzer.base_analyzer import BaseAnalyzer -from profiler.advisor.display.html.render import HTMLRender -from profiler.advisor.result.result import OptimizeResult -from profiler.compare_tools.compare_backend.utils.constant import Constant -from profiler.compare_tools.compare_interface.comparison_interface import ComparisonInterface - -logger = logging.getLogger() - - -class OverallSummaryAnalyzer(BaseAnalyzer): - - def __init__(self, profiling_path, benchmark_profiling_path=None, **kwargs): - self.benchmark_profiling_path = benchmark_profiling_path or profiling_path - self.profiling_path = profiling_path - self.html_render = HTMLRender() - self.result = OptimizeResult() - - def optimize(self, **kwargs): - compare_result = ComparisonInterface(self.benchmark_profiling_path, self.profiling_path).compare( - Constant.OVERALL_COMPARE) - - headers = compare_result.get('Model Profiling Time Distribution').get("headers", []) - rows = compare_result.get('Model Profiling Time Distribution').get("rows", []) - - self.make_record() - self.make_render(headers=headers, rows=rows) - return compare_result - - def make_record(self): - pass - - def make_render(self, **kwargs): - headers = kwargs.get("headers") - rows = kwargs.get("rows") - - if not headers or not rows: - logger.info("Empty headers or rows, skip render overall analysis html") - self.html_render.render_template(key="overall", - template_dir="templates", - template_name="overall_analysis.html", - headers=kwargs.get("headers"), - rows=kwargs.get("rows")) diff --git a/profiler/advisor/analyzer/overall/overall_summary_analyzer.py b/profiler/advisor/analyzer/overall/overall_summary_analyzer.py index c74ae05103..bfe0ed6ecc 100644 --- a/profiler/advisor/analyzer/overall/overall_summary_analyzer.py +++ b/profiler/advisor/analyzer/overall/overall_summary_analyzer.py @@ -12,20 +12,17 @@ # 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 os import copy - -import logging +import os from typing import Dict, List +from profiler.advisor.analyzer.base_analyzer import BaseAnalyzer +from profiler.advisor.common import constant as const from profiler.advisor.display.html.render import HTMLRender -from profiler.advisor.result.result import OptimizeResult from profiler.advisor.result.item import OptimizeItem, OptimizeRecord -from profiler.advisor.analyzer.base_analyzer import BaseAnalyzer +from profiler.advisor.result.result import OptimizeResult from profiler.compare_tools.compare_backend.utils.constant import Constant -from profiler.advisor.common import constant as const from profiler.compare_tools.compare_interface.comparison_interface import ComparisonInterface -from profiler.advisor.utils.utils import get_file_path_from_directory, load_parameter class OverallSummaryAnalyzer(BaseAnalyzer): @@ -93,6 +90,23 @@ class OverallSummaryAnalyzer(BaseAnalyzer): return float("inf") return dividend / divisor + + @staticmethod + def __format_data(data: Dict) -> List: + """ + ref: OverallPerformanceComparator._compare + """ + formatted_data = [ + data.get("profiling_type"), + f"{data.get('other_time'):.3f}s", + f"{data.get('compute_time'):.3f}s", + f"{data.get('communication_not_overlapped'): .3f}s({data.get('wait_time'):.3f}s)" if data.get( + "wait_time") else f"{data.get('communication_not_overlapped'): .3f}s( / )", + f"{data.get('scheduling_time'):.3f}s", + f"{data.get('e2e_time'):.3f}s", + ] + return formatted_data + def path_check(self): if self.base_collection_path: if os.path.exists(self.base_collection_path): @@ -102,19 +116,22 @@ class OverallSummaryAnalyzer(BaseAnalyzer): return os.path.exists(self.collection_path) def process(self): + # -bp暂无相关能力,这里暂且都读取base_collection_path base_collection_path = self.base_collection_path if self._has_base_collection else self.collection_path - result_data = ComparisonInterface(base_collection_path, self.collection_path).compare(Constant.OVERALL_COMPARE) - for data in result_data.values(): - self._headers = data.get("headers", []) - rows = data.get("rows", []) - if len(rows) == 2: - self._base_data = rows[0] - self._comparison_data = rows[1] + base_data_raw = ComparisonInterface(base_collection_path).disaggregate_perf(Constant.OVERALL_COMPARE) + base_data = self.__format_data(base_data_raw) + self._base_data = base_data + self._comparison_data = base_data + + self._headers = ["", "Other Time", "Computing Time", "Mem Usage", "Uncovered Communication Time(Wait Time)", + "Free Time", "E2E Time(Not minimal profiling)"] + + if not self._headers or not self._comparison_data: return - self._is_minimal_profiling = 'E2E Time(Not minimal profiling)' not in self._headers + self._is_minimal_profiling = "E2E Time(Not minimal profiling)" not in self._headers if self._has_base_collection: - self.cur_data["comparison_result"] = result_data + self.cur_data["comparison_result"] = [base_data, base_data] time_category_dict = {} for time_category, time_list in self.performance_time_dict.items(): time_value = self.get_time_value(time_category, self._comparison_data) @@ -178,6 +195,7 @@ class OverallSummaryAnalyzer(BaseAnalyzer): self.cur_bottleneck["overall_data"] = overall_bottleneck if comparison_bottleneck: self.cur_bottleneck["comparison_result"] = comparison_bottleneck + def optimize(self, **kwargs): if self.path_check(): self.process() @@ -218,7 +236,6 @@ class OverallSummaryAnalyzer(BaseAnalyzer): data_table = {"headers": headers, "data": [data_list]} self.cur_data_table[data_type] = copy.deepcopy(data_table) - def make_record(self): """ make record for what and how to optimize @@ -232,7 +249,7 @@ class OverallSummaryAnalyzer(BaseAnalyzer): ) self.result.add(OptimizeRecord(optimization_item)) - self.result.add_detail(const.BOTTLENECK, self.bottleneck_table["headers"], self.bottleneck_table["data"][0]) + self.result.add_detail(const.BOTTLENECK, self.bottleneck_table["headers"], self.bottleneck_table["data"][0]) for data_type, data_dict in self.cur_data_table.items(): if data_dict: self.result.add_detail(const.DATA + data_type, data_dict["headers"], data_dict["data"][0]) @@ -241,9 +258,9 @@ class OverallSummaryAnalyzer(BaseAnalyzer): if not self.bottleneck_str and not self.cur_advices: return result_for_html = { - "Description" : self.bottleneck_str, - "suggestion" : self.cur_advices, - "details" : [self.bottleneck_table] + "Description": self.bottleneck_str, + "suggestion": self.cur_advices, + "details": [self.bottleneck_table] } self.html_render.render_template(key="overall", @@ -254,9 +271,10 @@ class OverallSummaryAnalyzer(BaseAnalyzer): torch_version=self.torch_version, result=result_for_html) + def get_profile_path(collection_path): for root, dirs, files in os.walk(collection_path): for file in files: if file.startswith("profiler_info"): return root - return "" \ No newline at end of file + return "" -- Gitee