diff --git a/profiler/merge_profiling_timeline/README.md b/profiler/merge_profiling_timeline/README.md index 822cce3e80c8e03424fb7cc709a89d68ab9ce494..22516739cd7d1a5d0654faae5bc1cea6c3e5e643 100644 --- a/profiler/merge_profiling_timeline/README.md +++ b/profiler/merge_profiling_timeline/README.md @@ -9,7 +9,7 @@ ### 1.1 数据采集 -使用msporf采集数据,将采集到的所有节点的profiling数据拷贝到当前机器同一目录下,以下假设数据在/home/test/cann_profiling下 +使用msprof采集数据,将采集到的所有节点的profiling数据拷贝到当前机器同一目录下,以下假设数据在/home/test/cann_profiling下 e2e profiling数据目录结构如下: @@ -43,40 +43,38 @@ ascend pytorch profiler数据目录结构如下: 可选参数: - -d: **必选参数**,profiling数据文件或文件夹路径 -- -o: 可选参数,指定合并后的timeline文件输出的路径,默认为'-d'输入的路径 -- --rank:可选参数,指定需要合并timeline的卡号,默认全部合并 -- --items:可选参数,指定需要合并的profiling数据项,默认全部合并 -- --type: 指定需要合并timeline场景,可选参数:`pytorch`, `e2e`, `custom` +- --type: **必选参数**,指定需要合并timeline场景,可选参数有:`pytorch`, `e2e`, `custom` - `pytorch`:通过ascend pytorch方式采集profiling数据,合并所有卡的trace_view.json - `e2e`:通过e2e方式采集profiling数据,优先合并总timeline,没有生成则选择合并device目录下的msprof_*.json - `custom` :自定义需要合并的timeline数据,具体参考示例 - - +- -o: 可选参数,指定合并后的timeline文件输出的路径(路径末尾可以设置文件名,具体用法参考示例),默认为'-d'输入的路径 +- --rank:可选参数,指定需要合并timeline的卡号,默认全部合并 +- --items:可选参数,指定需要合并的profiling数据项(python,Ascend Hardware,CANN,HCCL,PTA,Overlap Analysis),默认全部合并 **使用示例**: - -1、合并单机多卡timeline,默认合并所有卡、所有数据项: +1、合并单机多卡timeline,默认合并所有卡、所有数据项,生成first_merge.json在path/to/cann_profiling/output/目录下(不设置-o参数时默认生成_merge.json在数据目录(path/to/cann_profiling/)下: ``` -python3 main.py -d path/to/cann_profiling/ +python3 main.py -d path/to/cann_profiling/ -o path/to/cann_profiling/output/first --type pytorch ``` 2、合并单机多卡timeline,只合并0卡和1卡: ``` -python3 main.py -d path/to/cann_profiling/ --rank 0,1 +python3 main.py -d path/to/cann_profiling/ -o path/to/cann_profiling/output/2p --type pytorch --rank 0,1 ``` 3、合并单机多卡timeline,合并所有卡的CANN层和Ascend_Hardware层数据 ``` -python3 main.py -d path/to/cann_profiling/ --items CANN,Ascend_Hardware +python3 main.py -d path/to/cann_profiling/ --type pytorch --items CANN,Ascend_Hardware ``` 4、合并多timeline(自定义) -以上场景不支持的情况下,可以使用自定义的合并方式,将需要合并的timeline文件放在同一目录下,数据目录结构示意如下: +以上场景不支持的情况下,可以使用自定义的合并方式,将需要合并的timeline文件放在同一目录下(附:该场景比较特殊,与正常合并不同,无法直接读取info.json中的rank_id, 因此该场景下的rank_id为默认分配的序号,用于区分不同文件的相同层,不代表实际rank_id) +数据目录结构示意如下: ``` |- timeline @@ -101,18 +99,21 @@ python3 main.py -d path/to/timeline/ --type custom 合并timeline查看: -> 在 -o 指定的目录(默认在-d指定的目录下)的msprof_merged_*p.json为合并后的文件 +> 在 -o 指定的目录(默认在-d指定的目录下)的_merged.json为合并后的文件 ## 2 超大timeline文件查看 下载whl包并安装(windows): https://gitee.com/aerfaliang/trace_processor/releases/download/trace_processor_37.0/trace_processor-37.0-py3-none-any.whl +``` +pip3 install trace_processor-37.0-py3-none-any.whl +``` 安装完成后直接使用以下命令 ``` -python3 ./trace_processor --httpd path/to/msprof_merged_*p.json +python -m trace_processor --httpd path/to/xxx_merged.json ``` -等待加载完毕,刷新[perfetto](https://ui.perfetto.dev/)界面,点击`YES, use loaded trace`即可展示timeline \ No newline at end of file +等待加载完毕,刷新[perfetto](https://ui.perfetto.dev/)界面,点击Use old version regardless,再点击`YES, use loaded trace`即可展示timeline diff --git a/profiler/merge_profiling_timeline/main.py b/profiler/merge_profiling_timeline/main.py index c2b3be9ca160fefede5737ba8e119c653561830d..5ac4b89e0c8c25acd266d7b96ac40f7985bf89a1 100644 --- a/profiler/merge_profiling_timeline/main.py +++ b/profiler/merge_profiling_timeline/main.py @@ -22,7 +22,7 @@ from argparse import ArgumentParser FILTER_DIRS = [".profiler", "HCCL_PROF", "timeline", "query", 'sqlite', 'log'] -MAX_INDEX_COUNT = 1000 +RANK_ID_POS = 1000 # 获取时间差异文件中的node和时间差的对应关系,保存到字典中 @@ -144,6 +144,9 @@ def merge_timeline_general(args): rank_ids = list(timeline_info.keys()) for rank_id in rank_ids: + if not timeline_info.get(rank_id): + print(f"main.py: error rank_id '{rank_id}' ") + return timeline_files_dict[rank_id] = timeline_info.get(rank_id) merge_timeline_events(timeline_files_dict, process_list) @@ -219,21 +222,24 @@ def merge_timeline_events(timeline_file_dict, process_list): if event.get("args") is not None and event["args"].get("name") is not None: event["args"]["name"] = event["args"]["name"] + f"_{rank_id}" + #modify connect id + if event.get('id') and (event.get('ph') == 's' or event.get('ph') == 'f'): + event['id'] = float(event.get('id')) * RANK_ID_POS + rank_id + new_events.append(event) - output_path = os.path.join(args.output, f"msprof_merged_{len(timeline_file_dict)}p.json") - with open(output_path, 'w') as f: + out_path = f"{args.output}_merged.json" + with open(out_path, 'w') as f: json.dump(new_events, f) - print(f"timeline merged output path: {output_path}") + print(f"timeline merged output path: {out_path}") def parse_args(): parser = ArgumentParser(description="Merge timeline for multi card") parser.add_argument("--data", "-d", default=None, help="root dir of PROF_* data") - parser.add_argument("--timediff", "-t", default=None, help="JSON file for saving startup time differences") parser.add_argument("--output", "-o", default=None, help="save path of msprof_merged.json ") parser.add_argument("--rank", default=None, help="List of ranks to be merged. By default, all ranks are merged") - parser.add_argument("--items", default=None, help="Specify the data items to be merged. in the timeline.") + parser.add_argument("--items", default=None, help="Specify the data items (python,CANN,Ascend Hardware,HCCL,..)to be merged. in the timeline.") parser.add_argument("--type", choices=('pytorch', 'e2e', 'custom'), help="Customize the timeline file to be merged.") arg = parser.parse_args() return arg