已合并
adapt dpu data #208
wangzixuan创建于 4月25日
adapt dpu data #208
已合并
wangzixuan创建于 4月25日
20 个文件变更+725-19
@@ -475,3 +475,11 @@ class AiStackDataCheckManager(DataCheckManager):
475 """475 """
476 return cls.check_data_exist(result_dir, file_name_manager.get_v5_stars_profile_compiles(),476 return cls.check_data_exist(result_dir, file_name_manager.get_v5_stars_profile_compiles(),
477 device_id=device_id)477 device_id=device_id)
478+ 
479+ @classmethod
480+ def contain_dpu_data(cls: any, result_dir: str, device_id: any = None) -> bool:
481+ """
482+ The data path contain dpu data or not
483+ """
484+ return cls.check_data_exist(result_dir, file_name_manager.get_dpu_track_compact_compiles()) or \
485+ cls.check_data_exist(result_dir, file_name_manager.get_dpu_hccl_track_compact_compiles())
@@ -110,6 +110,7 @@ class DBNameConstant(metaclass=ABCMeta):
110 DB_SOC_PMU = "soc_pmu.db"110 DB_SOC_PMU = "soc_pmu.db"
111 DB_VOLTAGE = "voltage.db"111 DB_VOLTAGE = "voltage.db"
112 DB_FUSION_TASK = "fusion_task.db"112 DB_FUSION_TASK = "fusion_task.db"
113+ DB_DPU = "dpu.db"
113 114 
114 # DB tables115 # DB tables
115 TABLE_ACL_DATA = "AclData"116 TABLE_ACL_DATA = "AclData"
@@ -355,6 +356,10 @@ class DBNameConstant(metaclass=ABCMeta):
355 TABLE_HCCL_OP_INFO = "HcclOpInfo"356 TABLE_HCCL_OP_INFO = "HcclOpInfo"
356 TABLE_STREAM_EXPAND_SPEC = "StreamExpandSpec"357 TABLE_STREAM_EXPAND_SPEC = "StreamExpandSpec"
357 358 
359+ # dpu
360+ TABLE_DPU_TASK_TRACK = "DPUTaskTrack"
361+ TABLE_DPU_HCCL_TRACK = 'DPUHcclTrack'
362+ 
358 # v5363 # v5
359 TABLE_V5_TASK = "V5Task"364 TABLE_V5_TASK = "V5Task"
360 365 
@@ -250,6 +250,10 @@ class FileNameManagerConstant:
250 AICPU_FILE_PATTERN = r"^aicpu\.data\.(\d+)\.slice_\d+"250 AICPU_FILE_PATTERN = r"^aicpu\.data\.(\d+)\.slice_\d+"
251 HCCL_OP_INFO_FILE_PATTERN = r"^(unaging|aging)\.compact\.hccl_op_info\.slice_\d+"251 HCCL_OP_INFO_FILE_PATTERN = r"^(unaging|aging)\.compact\.hccl_op_info\.slice_\d+"
252 252 
253+ # dpu
254+ DPU_TASK_TRACK_FILE_PATTERN = r"^(aging|unaging)\.compact\.dpu_track\.slice_\d+"
255+ DPU_HCCL_TRACK_FILE_PATTERN = r"^(aging|unaging)\.additional\.dpu_hccl_track\.slice_\d+"
256+ 
253 # V5257 # V5
254 V5_MODEL_EXEOM_PATTERN = r"^unaging\.additional\.model_exeom\.slice_\d+"258 V5_MODEL_EXEOM_PATTERN = r"^unaging\.additional\.model_exeom\.slice_\d+"
255 V5_STARS_PROFILE_PATTERN = r"^nano_stars_profile\.data.\d+\.slice_\d+"259 V5_STARS_PROFILE_PATTERN = r"^nano_stars_profile\.data.\d+\.slice_\d+"
@@ -1171,3 +1175,21 @@ def get_dbg_file_compiles() -> tuple:
1171 :return: v5 host info files regex1175 :return: v5 host info files regex
1172 """1176 """
1173 return (re.compile(FileNameManagerConstant.DBG_PATTERN),)1177 return (re.compile(FileNameManagerConstant.DBG_PATTERN),)
1178+ 
1179+ 
1180+def get_dpu_track_compact_compiles() -> tuple:
1181+ """
1182+ get dpu task track regex compiles
1183+ """
1184+ return (
1185+ re.compile(FileNameManagerConstant.DPU_TASK_TRACK_FILE_PATTERN),
1186+ )
1187+ 
1188+ 
1189+def get_dpu_hccl_track_compact_compiles() -> tuple:
1190+ """
1191+ get runtime task track regex compiles
1192+ """
1193+ return (
1194+ re.compile(FileNameManagerConstant.DPU_HCCL_TRACK_FILE_PATTERN),
1195+ )
@@ -113,7 +113,7 @@ class PathManager:
113 DBNameConstant.DB_MULTI_THREAD, DBNameConstant.DB_TENSOR_ADD_INFO, DBNameConstant.DB_NODE_BASIC_INFO,113 DBNameConstant.DB_MULTI_THREAD, DBNameConstant.DB_TENSOR_ADD_INFO, DBNameConstant.DB_NODE_BASIC_INFO,
114 DBNameConstant.DB_FUSION_ADD_INFO, DBNameConstant.DB_GRAPH_ADD_INFO, DBNameConstant.DB_CTX_ID,114 DBNameConstant.DB_FUSION_ADD_INFO, DBNameConstant.DB_GRAPH_ADD_INFO, DBNameConstant.DB_CTX_ID,
115 DBNameConstant.DB_SYNC_ACL_NPU, DBNameConstant.DB_MEMORY_OP, DBNameConstant.DB_GE_LOGIC_STREAM_INFO,115 DBNameConstant.DB_SYNC_ACL_NPU, DBNameConstant.DB_MEMORY_OP, DBNameConstant.DB_GE_LOGIC_STREAM_INFO,
116- DBNameConstant.DB_MC2_COMM_INFO, DBNameConstant.DB_STREAM_INFO116+ DBNameConstant.DB_MC2_COMM_INFO, DBNameConstant.DB_STREAM_INFO, DBNameConstant.DB_DPU
117 }117 }
118 base_result_dir = result_dir118 base_result_dir = result_dir
119 if db_name in db_filter:119 if db_name in db_filter:
@@ -81,9 +81,11 @@ class TraceViewHeaderConstant:
81 PROCESS_VOLTAGE = "Voltage Info"81 PROCESS_VOLTAGE = "Voltage Info"
82 PROCESS_AI_CORE_VOLTAGE = "Aicore Voltage"82 PROCESS_AI_CORE_VOLTAGE = "Aicore Voltage"
83 PROCESS_BUS_VOLTAGE = "Bus Voltage"83 PROCESS_BUS_VOLTAGE = "Bus Voltage"
84+ PROCESS_DPU = "DPU"
84 85 
85 # trace general layer86 # trace general layer
86 GENERAL_LAYER_CPU = "CPU"87 GENERAL_LAYER_CPU = "CPU"
88+ GENERAL_LAYER_DPU = "DPU"
87 GENERAL_LAYER_NPU = "NPU"89 GENERAL_LAYER_NPU = "NPU"
88 90 
89 # trace component layer91 # trace component layer
@@ -98,6 +100,7 @@ class TraceViewHeaderConstant:
98 COMPONENT_LAYER_AICORE_FREQ = "AI Core Freq"100 COMPONENT_LAYER_AICORE_FREQ = "AI Core Freq"
99 COMPONENT_LAYER_HCCL = "Communication"101 COMPONENT_LAYER_HCCL = "Communication"
100 COMPONENT_LAYER_VOLTAGE = "Voltage Info"102 COMPONENT_LAYER_VOLTAGE = "Voltage Info"
103+ COMPONENT_LAYER_DPU = "DPU"
101 104 
102 # filtering msprof timeline trace105 # filtering msprof timeline trace
103 MSPROF_TIMELINE_FILTER_LIST = (PROCESS_ALL_REDUCE, PROCESS_AI_CPU)106 MSPROF_TIMELINE_FILTER_LIST = (PROCESS_ALL_REDUCE, PROCESS_AI_CPU)
@@ -105,16 +108,17 @@ class TraceViewHeaderConstant:
105 # component_layer_sort108 # component_layer_sort
106 LAYER_FRAMEWORK_SORT = 6109 LAYER_FRAMEWORK_SORT = 6
107 LAYER_CANN_SORT = 7110 LAYER_CANN_SORT = 7
108- LAYER_CPU_USAGE_SORT = 8111+ LAYER_DPU_SORT = 8
109- LAYER_MEMORY_USAGE_SORT = 9112+ LAYER_CPU_USAGE_SORT = 9
110- LAYER_NETWORK_USAGE_SORT = 10113+ LAYER_MEMORY_USAGE_SORT = 10
111- LAYER_DISK_USAGE_SORT = 11114+ LAYER_NETWORK_USAGE_SORT = 11
112- LAYER_OS_RUNTIME_API_SORT = 12115+ LAYER_DISK_USAGE_SORT = 12
113- LAYER_ASCEND_HW_SORT = 13116+ LAYER_OS_RUNTIME_API_SORT = 13
114- LAYER_ASCEND_AICORE_FREQ_SORT = 14117+ LAYER_ASCEND_HW_SORT = 14
115- LAYER_VOLTAGE_SORT = 15118+ LAYER_ASCEND_AICORE_FREQ_SORT = 15
116- LAYER_HCCL = 16119+ LAYER_VOLTAGE_SORT = 16
117- DEFAULT_LAYER_SORT_START = 17120+ LAYER_HCCL_SORT = 17
121+ DEFAULT_LAYER_SORT_START = 18
118 122 
119 # namedtuple configuration of LayerInfo123 # namedtuple configuration of LayerInfo
120 LayerInfo = namedtuple('LayerInfo', ['component_layer', 'general_layer', 'sort_index'])124 LayerInfo = namedtuple('LayerInfo', ['component_layer', 'general_layer', 'sort_index'])
@@ -138,7 +142,8 @@ class TraceViewHeaderConstant:
138 PROCESS_OS_RUNTIME_API: LayerInfo(COMPONENT_LAYER_OS_RUNTIME_API, GENERAL_LAYER_CPU, LAYER_OS_RUNTIME_API_SORT),142 PROCESS_OS_RUNTIME_API: LayerInfo(COMPONENT_LAYER_OS_RUNTIME_API, GENERAL_LAYER_CPU, LAYER_OS_RUNTIME_API_SORT),
139 PROCESS_AI_CORE_FREQ: LayerInfo(COMPONENT_LAYER_AICORE_FREQ, GENERAL_LAYER_NPU, LAYER_ASCEND_AICORE_FREQ_SORT),143 PROCESS_AI_CORE_FREQ: LayerInfo(COMPONENT_LAYER_AICORE_FREQ, GENERAL_LAYER_NPU, LAYER_ASCEND_AICORE_FREQ_SORT),
140 PROCESS_VOLTAGE: LayerInfo(COMPONENT_LAYER_VOLTAGE, GENERAL_LAYER_NPU, LAYER_VOLTAGE_SORT),144 PROCESS_VOLTAGE: LayerInfo(COMPONENT_LAYER_VOLTAGE, GENERAL_LAYER_NPU, LAYER_VOLTAGE_SORT),
141- PROCESS_COMMUNICATION: LayerInfo(COMPONENT_LAYER_HCCL, GENERAL_LAYER_NPU, LAYER_HCCL),145+ PROCESS_COMMUNICATION: LayerInfo(COMPONENT_LAYER_HCCL, GENERAL_LAYER_NPU, LAYER_HCCL_SORT),
146+ PROCESS_DPU: LayerInfo(COMPONENT_LAYER_DPU, GENERAL_LAYER_DPU, LAYER_DPU_SORT),
142 }147 }
143 148 
144 @classmethod149 @classmethod
@@ -157,7 +157,10 @@ class TraceViewManager:
157 :return: format_pid: Uint32: pid use high 22bit, index_id use middle 5bit, device_id use low 5bit157 :return: format_pid: Uint32: pid use high 22bit, index_id use middle 5bit, device_id use low 5bit
158 ps: pid_max is 10^22 - 1158 ps: pid_max is 10^22 - 1
159 """159 """
160- if layer_info.general_layer == TraceViewHeaderConstant.GENERAL_LAYER_CPU or \160+ if layer_info.general_layer == TraceViewHeaderConstant.GENERAL_LAYER_DPU:
161+ device_id = pid
162+ pid = InfoConfReader().get_json_pid_data()
163+ elif layer_info.general_layer == TraceViewHeaderConstant.GENERAL_LAYER_CPU or \
161 not is_number(InfoConfReader().get_device_id()):164 not is_number(InfoConfReader().get_device_id()):
162 # host device_id is 31, we cannot use NumberConstant.HOST_ID,165 # host device_id is 31, we cannot use NumberConstant.HOST_ID,
163 # cause this value is also been used in record time.166 # cause this value is also been used in record time.
@@ -103,6 +103,8 @@ from common_func.file_name_manager import get_soc_pmu_compiles
103from common_func.file_name_manager import get_lpm_info_compiles103from common_func.file_name_manager import get_lpm_info_compiles
104from common_func.file_name_manager import get_host_stream_expand_spec_info_compiles104from common_func.file_name_manager import get_host_stream_expand_spec_info_compiles
105from common_func.file_name_manager import get_runtime_op_info_compiles105from common_func.file_name_manager import get_runtime_op_info_compiles
106+from common_func.file_name_manager import get_dpu_track_compact_compiles
107+from common_func.file_name_manager import get_dpu_hccl_track_compact_compiles
106from common_func.ms_constant.str_constant import StrConstant108from common_func.ms_constant.str_constant import StrConstant
107from common_func.path_manager import PathManager109from common_func.path_manager import PathManager
108from framework.prof_factory_maker import ProfFactoryMaker110from framework.prof_factory_maker import ProfFactoryMaker
@@ -201,6 +203,8 @@ class FileDispatch:
201 DataTag.V5_MODEL_EXEOM: get_v5_model_exeom_compiles(),203 DataTag.V5_MODEL_EXEOM: get_v5_model_exeom_compiles(),
202 DataTag.V5_STARS_PROFILE: get_v5_stars_profile_compiles(),204 DataTag.V5_STARS_PROFILE: get_v5_stars_profile_compiles(),
203 DataTag.DBG_FILE: get_dbg_file_compiles(),205 DataTag.DBG_FILE: get_dbg_file_compiles(),
206+ DataTag.DPU_TASK_TRACK: get_dpu_track_compact_compiles(),
207+ DataTag.DPU_HCCL_TRACK: get_dpu_hccl_track_compact_compiles(),
204 }208 }
205 209 
206 def __init__(self: any, sample_config: dict) -> None:210 def __init__(self: any, sample_config: dict) -> None:
@@ -1334,6 +1334,46 @@ class TablesConfig(MetaConfig):
1334 ('timestamp', 'NUMERIC,null'),1334 ('timestamp', 'NUMERIC,null'),
1335 ('connection_id', 'INTEGER,null'),1335 ('connection_id', 'INTEGER,null'),
1336 ],1336 ],
1337+ 'DPUTaskTrackMap': [
1338+ ('dpu_device_id', 'INTEGER,null'),
1339+ ('thread_id', 'INTEGER,null'),
1340+ ('start_time', 'NUMERIC,null'),
1341+ ('end_time', 'NUMERIC,null'),
1342+ ('task_type', 'TEXT,null'),
1343+ ('stream_id', 'INTEGER,null'),
1344+ ('task_id', 'INTEGER,null'),
1345+ ('kernel_name', 'TEXT,null'),
1346+ ],
1347+ 'DPUHcclTrackMap': [
1348+ ('npu_device_id', 'INTEGER,null'),
1349+ ('dpu_device_id', 'INTEGER,null'),
1350+ ('thread_id', 'INTEGER,null'),
1351+ ('start_time', 'NUMERIC,null'),
1352+ ('end_time', 'NUMERIC,null'),
1353+ ('op_name', 'TEXT,null'),
1354+ ('group_name', 'TEXT,null'),
1355+ ('local_rank', 'INTEGER,null'),
1356+ ('remote_rank', 'INTEGER,null'),
1357+ ('rank_size', 'INTEGER,null'),
1358+ ('duration_estimated', 'NUMERIC,null'),
1359+ ('src_addr', 'TEXT,null'),
1360+ ('dst_addr', 'TEXT,null'),
1361+ ('data_size', 'INTEGER,null'),
1362+ ('stream_id', 'INTEGER,null'),
1363+ ('task_id', 'INTEGER,null'),
1364+ ('aicpu_task_id', 'INTEGER,null'),
1365+ ('plane_id', 'INTEGER,null'),
1366+ ('op_type', 'TEXT,null'),
1367+ ('data_type', 'TEXT,null'),
1368+ ('link_type', 'TEXT,null'),
1369+ ('transport_type', 'TEXT,null'),
1370+ ('rdma_type', 'TEXT,null'),
1371+ ('role', 'TEXT,null'),
1372+ ('ccl_tag', 'TEXT,null'),
1373+ ('notify_id', 'TEXT,null'),
1374+ ('work_flow_mode', 'TEXT,null'),
1375+ ('stage', 'TEXT,null')
1376+ ],
1337 'AscendTaskMap': [1377 'AscendTaskMap': [
1338 ('model_id', 'INTEGER,null'),1378 ('model_id', 'INTEGER,null'),
1339 ('index_id', 'INTEGER,null'),1379 ('index_id', 'INTEGER,null'),
The file is empty
@@ -0,0 +1,73 @@
1+# -------------------------------------------------------------------------
2+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+# This file is part of the MindStudio project.
4+#
5+# MindStudio is licensed under Mulan PSL v2.
6+# You can use this software according to the terms and conditions of the Mulan PSL v2.
7+# You may obtain a copy of Mulan PSL v2 at:
8+#
9+# http://license.coscl.org.cn/MulanPSL2
10+#
11+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
12+# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
13+# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
14+# See the Mulan PSL v2 for more details.
15+# -------------------------------------------------------------------------
16+ 
17+import logging
18+ 
19+from common_func.db_manager import DBManager
20+from common_func.db_name_constant import DBNameConstant
21+from common_func.ms_constant.str_constant import StrConstant
22+from msmodel.interface.parser_model import ParserModel
23+from msmodel.interface.view_model import ViewModel
24+from profiling_bean.db_dto.dpu_track_dto import DPUTrackDto
25+ 
26+ 
27+class DPUTaskModel(ParserModel):
28+ """
29+ class used to operate all dpu track
30+ """
31+ 
32+ def __init__(self: any, result_dir: str) -> None:
33+ super(DPUTaskModel, self).__init__(result_dir, DBNameConstant.DB_DPU,
34+ [DBNameConstant.TABLE_DPU_TASK_TRACK, DBNameConstant.TABLE_DPU_HCCL_TRACK])
35+ 
36+ def flush(self: any, data_list: list, table_name: str = DBNameConstant.TABLE_DPU_TASK_TRACK) -> None:
Wangang Yu
Wangang YuWangang Yu5月25日

[review] 问题: data_list: list 类型过于宽泛,未说明元素类型。 影响:调用方无法明确需要传入什么结构的数据,后续维护和静态检查困难。 建议: 建议改成更明确的类型,例如 list[DPUTrackDto]、list[tuple] 或 Sequence[...],根据 insert_data_to_db 实际要求确定。

likedislike
37+ """
38+ flush to db
39+ :param data_list: data
40+ :param table_name: table name
41+ :return:
42+ """
43+ self.insert_data_to_db(table_name, data_list)
44+ 
45+ 
46+class DPUTaskViewModel(ViewModel):
47+ """
48+ class for dpu task viewer
49+ """
50+ 
51+ def __init__(self: any, result_dir: str, db_name: str, table_list: list) -> None:
Wangang Yu
Wangang YuWangang Yu5月25日

[review] 问题:db_name 和 table_list 完全由外部传入,但类名是 DPUTaskViewModel,理论上应绑定 DPU 相关 DB 和表。 影响:调用方可能传入错误 DB 或表,导致 get_timeline_data 查询固定 DPU 表时与初始化表列表不一致。 建议: 如果该类只服务 DPU,建议构造函数内部固定使用 DBNameConstant.DB_DPU 和 DPU 表列表;如果必须外部传参,需要校验参数合法性。

likedislike
52+ super().__init__(result_dir, db_name, table_list)
53+ 
54+ def get_timeline_data(self: any) -> tuple:
Wangang Yu
Wangang YuWangang Yu5月25日

[review] 问题: DPUTrackDto 同时用于 task track 和 HCCL track 两种字段数量、字段语义明显不同的数据。 影响:DTO 字段如果不完全兼容,可能出现字段错位、属性缺失或后续解析逻辑混乱。 建议: 建议分别定义 DPUTaskTrackDto 和 DPUHcclTrackDto;如果必须复用,需要确认 DTO 明确支持两类查询结果,并补充注释说明

likedislike
55+ task_track = []
56+ hccl_track = []
57+ if DBManager.judge_table_exist(self.cur, DBNameConstant.TABLE_DPU_TASK_TRACK):
58+ sql = "select dpu_device_id, thread_id, start_time, end_time, task_type, stream_id, task_id, kernel_name "\
59+ "from {} ".format(DBNameConstant.TABLE_DPU_TASK_TRACK)
60+ task_track = DBManager.fetch_all_data(self.cur, sql, dto_class=DPUTrackDto)
61+ 
62+ if DBManager.judge_table_exist(self.cur, DBNameConstant.TABLE_DPU_HCCL_TRACK):
63+ sql = "select npu_device_id, dpu_device_id, thread_id, start_time, end_time, op_name, group_name, " \
64+ "local_rank, remote_rank, rank_size, duration_estimated, src_addr, dst_addr, data_size, " \
65+ "stream_id, task_id, aicpu_task_id, plane_id, op_type, data_type, link_type, transport_type, " \
66+ "rdma_type, role, ccl_tag, notify_id, work_flow_mode, stage " \
67+ "from {} ".format(DBNameConstant.TABLE_DPU_HCCL_TRACK)
68+ hccl_track = DBManager.fetch_all_data(self.cur, sql, dto_class=DPUTrackDto)
69+ return task_track, hccl_track
70+ 
71+ 
72+ 
73+ 
@@ -0,0 +1,248 @@
1+# -------------------------------------------------------------------------
2+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+# This file is part of the MindStudio project.
4+#
5+# MindStudio is licensed under Mulan PSL v2.
6+# You can use this software according to the terms and conditions of the Mulan PSL v2.
7+# You may obtain a copy of Mulan PSL v2 at:
8+#
9+# http://license.coscl.org.cn/MulanPSL2
10+#
11+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
12+# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
13+# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
14+# See the Mulan PSL v2 for more details.
15+# -------------------------------------------------------------------------
16+ 
17+from msparser.add_info.add_info_bean import AddInfoBean
18+ 
19+ 
20+class DPUHcclTrackBean(AddInfoBean):
21+ """
22+ DPU hccl information bean data for the data parsing by acl parser.
23+ """
24+ 
25+ def __init__(self: any, *args) -> None:
26+ super().__init__(*args)
27+ filed = args[0]
28+ self._item_id = filed[6]
29+ self._ccl_tag = filed[7]
30+ self._group_name = filed[8]
31+ self._local_rank = filed[9]
32+ self._remote_rank = filed[10]
33+ self._rank_size = filed[11]
34+ self._stage = filed[12]
35+ self._notify_id = filed[13]
36+ self._start_time = filed[14]
37+ self._duration_estimated = filed[15]
38+ self._src_addr = filed[16]
39+ self._dst_addr = filed[17]
40+ self._data_size = filed[18]
41+ self._task_id = filed[19]
42+ self._aicpu_task_id = filed[20]
43+ self._stream_id = filed[21]
44+ self._plane_id = filed[22]
45+ self._npu_device_id = filed[23]
46+ self._dev_type = (filed[24] >> 12) & 0xF
47+ self._dpu_device_id = filed[24] & 0xFFF
48+ self._op_type = filed[25]
49+ self._data_type = filed[26]
50+ self._link_type = filed[27]
51+ self._transport_type = filed[28]
52+ self._rdma_type = filed[29]
53+ self._role = filed[30]
54+ self._work_flow_mode = filed[31]
55+ 
56+ @property
57+ def item_id(self: any) -> str:
58+ """
59+ hccl information id
60+ :return: hccl information id
61+ """
62+ return str(self._item_id)
63+ 
64+ @property
65+ def ccl_tag(self: any) -> str:
66+ """
67+ hash number for ccl
68+ :return: hash number for ccl
69+ """
70+ return str(self._ccl_tag)
71+ 
72+ @property
73+ def group_name(self: any) -> str:
74+ """
75+ hash number for ccl group
76+ :return: hash number for ccl group
77+ """
78+ return str(self._group_name)
79+ 
80+ @property
81+ def local_rank(self: any) -> int:
82+ """
83+ local rank number
84+ :return: local rank number
85+ """
86+ return self._local_rank
87+ 
88+ @property
89+ def remote_rank(self: any) -> int:
90+ """
91+ remote rank number
92+ :return: remote rank number
93+ """
94+ return self._remote_rank
95+ 
96+ @property
97+ def rank_size(self: any) -> int:
98+ """
99+ hccl information rank size
100+ """
101+ return self._rank_size
102+ 
103+ @property
104+ def stage(self: any) -> str:
105+ """
106+ communicate algorithm stage
107+ """
108+ return str(self._stage)
109+ 
110+ @property
111+ def notify_id(self: any) -> str:
112+ """
113+ notify id
114+ """
115+ return str(self._notify_id)
116+ 
117+ @property
118+ def start_time(self: any) -> int:
119+ """
120+ start time
121+ """
122+ return self._start_time
123+ 
124+ @property
125+ def duration_estimated(self: any) -> float:
126+ """
127+ duration estimated
128+ """
129+ return float(self._duration_estimated)
130+ 
131+ @property
132+ def src_addr(self: any) -> str:
133+ """
134+ source address
135+ """
136+ return str(self._src_addr)
137+ 
138+ @property
139+ def dst_addr(self: any) -> str:
140+ """
141+ destination address
142+ """
143+ return str(self._dst_addr)
144+ 
145+ @property
146+ def data_size(self: any) -> int:
147+ """
148+ data size
149+ """
150+ return self._data_size
151+ 
152+ @property
153+ def task_id(self: any) -> int:
154+ """
155+ task id
156+ """
157+ return self._task_id
158+ 
159+ @property
160+ def aicpu_task_id(self: any) -> int:
161+ """
162+ ai cpu task id
163+ """
164+ return self._aicpu_task_id
165+ 
166+ @property
167+ def stream_id(self: any) -> int:
168+ """
169+ stream id
170+ """
171+ return self._stream_id
172+ 
173+ @property
174+ def plane_id(self: any) -> int:
175+ """
176+ plane id
177+ """
178+ return self._plane_id
179+ 
180+ @property
181+ def npu_device_id(self: any) -> int:
182+ """
183+ npu device id
184+ """
185+ return self._npu_device_id
186+ 
187+ @property
188+ def is_dpu(self: any) -> bool:
189+ """
190+ Used to distinguish the device type(DPU:1/NPU:0) of tasks.
191+ """
192+ return bool(self._dev_type)
193+ 
194+ @property
195+ def dpu_device_id(self: any) -> int:
196+ """
197+ device id
198+ """
199+ return self._dpu_device_id
200+ 
201+ @property
202+ def op_type(self: any) -> str:
203+ """
204+ op type
205+ """
206+ return str(self._op_type)
207+ 
208+ @property
209+ def data_type(self: any) -> str:
210+ """
211+ data type
212+ """
213+ return str(self._data_type)
214+ 
215+ @property
216+ def link_type(self: any) -> str:
217+ """
218+ link type
219+ """
220+ return str(self._link_type)
221+ 
222+ @property
223+ def transport_type(self: any) -> str:
224+ """
225+ transport type
226+ """
227+ return str(self._transport_type)
228+ 
229+ @property
230+ def rdma_type(self: any) -> str:
231+ """
232+ RDMA type
233+ """
234+ return str(self._rdma_type)
235+ 
236+ @property
237+ def role(self: any) -> str:
238+ """
239+ role
240+ """
241+ return str(self._role)
242+ 
243+ @property
244+ def work_flow_mode(self: any) -> str:
245+ """
246+ mode of the work flow
247+ """
248+ return str(self._work_flow_mode)
@@ -86,7 +86,7 @@ class HcclInfoParser(DataParser, MsMultiProcess):
86 self.save()86 self.save()
87 87 
88 def reformat_data(self) -> list:88 def reformat_data(self) -> list:
89- type_info_data = HashDictData(self._project_path).get_type_hash_dict().get("hccl", {})89+ type_info_data = HashDictData(self._project_path).get_type_hash_dict().get("communication", {})
90 hash_data = HashDictData(self._project_path).get_ge_hash_dict()90 hash_data = HashDictData(self._project_path).get_ge_hash_dict()
91 reformat = []91 reformat = []
92 for data in self._hccl_info_data:92 for data in self._hccl_info_data:
@@ -87,7 +87,7 @@ class MultiThreadParser(DataParser, MsMultiProcess):
87 self.save()87 self.save()
88 88 
89 def reformat_data(self) -> list:89 def reformat_data(self) -> list:
90- type_info_data = HashDictData(self._project_path).get_type_hash_dict().get("hccl", {})90+ type_info_data = HashDictData(self._project_path).get_type_hash_dict().get("communication", {})
91 return [91 return [
92 [data.level, type_info_data.get(data.struct_type, data.struct_type), data.thread_id, data.data_len,92 [data.level, type_info_data.get(data.struct_type, data.struct_type), data.thread_id, data.data_len,
93 data.timestamp, data.thread_num, data.sub_thread_id]93 data.timestamp, data.thread_num, data.sub_thread_id]
@@ -24,13 +24,21 @@ class TaskTrackBean(CompactInfoBean):
24 def __init__(self: any, *args) -> None:24 def __init__(self: any, *args) -> None:
25 super().__init__(*args)25 super().__init__(*args)
26 data = args[0]26 data = args[0]
27- self._device_id = data[6]27+ self._dev_type = (data[6] >> 12) & 0xF
28+ self._device_id = data[6] & 0xFFF
28 self._stream_id = data[7]29 self._stream_id = data[7]
29 self._task_id = data[8]30 self._task_id = data[8]
30 self._batch_id = data[9]31 self._batch_id = data[9]
31 self._task_type = data[10]32 self._task_type = data[10]
32 self._kernel_name = data[11]33 self._kernel_name = data[11]
33 34 
35+ @property
36+ def is_dpu(self: any) -> bool:
37+ """
38+ Used to distinguish the device type(DPU:1/NPU:0) of tasks.
39+ """
40+ return bool(self._dev_type)
41+ 
34 @property42 @property
35 def device_id(self: any) -> int:43 def device_id(self: any) -> int:
36 """44 """
@@ -94,3 +102,53 @@ class TaskTrackChip6Bean(TaskTrackBean):
94 self._task_id = data[9] << 16 | data[8]102 self._task_id = data[9] << 16 | data[8]
95 self._batch_id = 0103 self._batch_id = 0
96 self._task_type = data[10]104 self._task_type = data[10]
105+ 
106+ 
107+class DPUTaskTrackBean(CompactInfoBean):
108+ """
109+ dpu start log bean
110+ """
111+ def __init__(self: any, *args) -> None:
112+ super().__init__(*args)
113+ data = args[0]
114+ self._dev_type = (data[6] >> 12) & 0xF
115+ self._device_id = data[6] & 0xFFF
116+ self._stream_id = data[7]
117+ self._task_id = data[8]
118+ self._task_type = data[9]
119+ self._start_time = data[11]
120+ 
121+ @property
122+ def device_id(self: any) -> int:
123+ """
124+ dpu task device_id
125+ """
126+ return self._device_id
127+ 
128+ @property
129+ def stream_id(self: any) -> int:
130+ """
131+ dpu task stream_id
132+ """
133+ return self._stream_id
134+ 
135+ @property
136+ def task_id(self: any) -> int:
137+ """
138+ dpu task task_id
139+ """
140+ return self._task_id
141+ 
142+ @property
143+ def task_type(self: any) -> str:
144+ """
145+ dpu task task_type
146+ """
147+ return str(self._task_type)
148+ 
149+ @property
150+ def start_time(self: any) -> int:
151+ """
152+ dpu task start_time
153+ """
154+ return self._start_time
@@ -212,6 +212,14 @@ class StructFmt:
212 TASK_TRACK_FMT = "HHIIIQHHHHQQ" + "B" * TASK_TRACK_RESIDUAL_SIZE212 TASK_TRACK_FMT = "HHIIIQHHHHQQ" + "B" * TASK_TRACK_RESIDUAL_SIZE
213 TASK_TRACK_DATA_SIZE = struct.calcsize(TASK_TRACK_FMT)213 TASK_TRACK_DATA_SIZE = struct.calcsize(TASK_TRACK_FMT)
214 214 
215+ # DPU
216+ DPU_TASK_TRACK_RESIDUAL_SIZE = 16
217+ DPU_TASK_TRACK_FMT = "HHIIIQHHIIIQ" + "B" * DPU_TASK_TRACK_RESIDUAL_SIZE
218+ DPU_TASK_TRACK_SIZE = struct.calcsize(DPU_TASK_TRACK_FMT)
219+ DPU_HCCL_TRACK_RESIDUAL_SIZE = 120
220+ DPU_HCCL_TRACK_FMT = "HHIIIQQQQIIIIQQQQQQIIHHHHBBBBBBBB" + "B" * DPU_HCCL_TRACK_RESIDUAL_SIZE
221+ DPU_HCCL_TRACK_SIZE = struct.calcsize(DPU_HCCL_TRACK_FMT)
222+ 
215 # capture223 # capture
216 CAPTURE_STREAM_INFO_RESIDUAL_SIZE = 32224 CAPTURE_STREAM_INFO_RESIDUAL_SIZE = 32
217 CAPTURE_STREAM_INFO_FMT = "HHIIIQHHHH" + "B" * CAPTURE_STREAM_INFO_RESIDUAL_SIZE225 CAPTURE_STREAM_INFO_FMT = "HHIIIQHHHH" + "B" * CAPTURE_STREAM_INFO_RESIDUAL_SIZE
@@ -0,0 +1,53 @@
1+# -------------------------------------------------------------------------
2+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+# This file is part of the MindStudio project.
4+#
5+# MindStudio is licensed under Mulan PSL v2.
6+# You can use this software according to the terms and conditions of the Mulan PSL v2.
7+# You may obtain a copy of Mulan PSL v2 at:
8+#
9+# http://license.coscl.org.cn/MulanPSL2
10+#
11+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
12+# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
13+# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
14+# See the Mulan PSL v2 for more details.
15+# -------------------------------------------------------------------------
16+ 
17+from dataclasses import dataclass
18+from common_func.constant import Constant
19+from profiling_bean.db_dto.dto_meta_class import InstanceCheckMeta
20+ 
21+ 
22+@dataclass
23+class DPUTrackDto(metaclass=InstanceCheckMeta):
24+ npu_device_id: int = Constant.DEFAULT_INVALID_VALUE
25+ dpu_device_id: int = Constant.DEFAULT_INVALID_VALUE
26+ start_time: int = Constant.DEFAULT_INVALID_VALUE
27+ end_time: int = Constant.DEFAULT_INVALID_VALUE
28+ stream_id: int = Constant.DEFAULT_INVALID_VALUE
29+ aicpu_task_id: int = Constant.DEFAULT_INVALID_VALUE
30+ task_id: int = Constant.DEFAULT_INVALID_VALUE
31+ task_type: str = Constant.NA
32+ kernel_name: str = Constant.NA
33+ ccl_tag: str = Constant.NA
34+ data_type: str = Constant.NA
35+ dst_addr: str = Constant.DEFAULT_INVALID_VALUE
36+ duration_estimated: int = Constant.DEFAULT_INVALID_VALUE
37+ group_name: str = Constant.NA
38+ link_type: str = Constant.NA
39+ local_rank: int = Constant.DEFAULT_INVALID_VALUE
40+ notify_id: int = Constant.DEFAULT_INVALID_VALUE
41+ op_name: str = Constant.NA
42+ op_type: str = Constant.NA
43+ plane_id: int = Constant.DEFAULT_INVALID_VALUE
44+ rank_size: int = Constant.DEFAULT_INVALID_VALUE
45+ rdma_type: str = Constant.NA
46+ remote_rank: int = Constant.DEFAULT_INVALID_VALUE
47+ role: str = Constant.NA
48+ data_size: int = Constant.DEFAULT_INVALID_VALUE
49+ src_addr: str = Constant.DEFAULT_INVALID_VALUE
50+ stage: str = Constant.DEFAULT_INVALID_VALUE
51+ thread_id: int = Constant.DEFAULT_INVALID_VALUE
52+ transport_type: str = Constant.NA
53+ work_flow_mode: str = Constant.NA
@@ -110,6 +110,8 @@ class DataTag(Enum):
110 LPM_INFO = 88110 LPM_INFO = 88
111 STREAM_EXPAND = 89111 STREAM_EXPAND = 89
112 RUNTIME_OP_INFO = 90112 RUNTIME_OP_INFO = 90
113+ DPU_HCCL_TRACK = 91
114+ DPU_TASK_TRACK = 92
113 115 
114 116 
115@unique117@unique
@@ -95,6 +95,8 @@ class StructDecoder:
95 "RuntimeOpInfo256Bean": StructFmt.RUNTIME_OP_INFO_256_FMT,95 "RuntimeOpInfo256Bean": StructFmt.RUNTIME_OP_INFO_256_FMT,
96 "V5ExeomBean": StructFmt.V5_MODEL_EXEOM_FMT,96 "V5ExeomBean": StructFmt.V5_MODEL_EXEOM_FMT,
97 "V5StarsBean": StructFmt.V5_STARS_PROFILE_FMT,97 "V5StarsBean": StructFmt.V5_STARS_PROFILE_FMT,
98+ "DPUHcclInfoBean":StructFmt.DPU_HCCL_TRACK_FMT,
99+ "DPUTaskTrackBean":StructFmt.DPU_TASK_TRACK_FMT,
98 }100 }
99 101 
100 @classmethod102 @classmethod
@@ -1,6 +1,18 @@
1-#!/usr/bin/python31+# -------------------------------------------------------------------------
2-# -*- coding: utf-8 -*-2+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
3-# Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.3+# This file is part of the MindStudio project.
4+#
5+# MindStudio is licensed under Mulan PSL v2.
6+# You can use this software according to the terms and conditions of the Mulan PSL v2.
7+# You may obtain a copy of Mulan PSL v2 at:
8+#
9+# http://license.coscl.org.cn/MulanPSL2
10+#
11+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
12+# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
13+# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
14+# See the Mulan PSL v2 for more details.
15+# -------------------------------------------------------------------------
4 16 
5from abc import ABC17from abc import ABC
6 18 
@@ -0,0 +1,163 @@
1+#!/usr/bin/env python
2+# coding=utf-8
3+# -------------------------------------------------------------------------
4+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
5+# This file is part of the MindStudio project.
6+#
7+# MindStudio is licensed under Mulan PSL v2.
8+# You can use this software according to the terms and conditions of the Mulan PSL v2.
9+# You may obtain a copy of Mulan PSL v2 at:
10+#
11+# http://license.coscl.org.cn/MulanPSL2
12+#
13+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
14+# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
15+# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
16+# See the Mulan PSL v2 for more details.
17+# -------------------------------------------------------------------------
18+ 
19+import unittest
20+ 
21+from common_func.trace_view_manager import TraceViewManager
22+from common_func.trace_view_header_constant import TraceViewHeaderConstant
23+from common_func.info_conf_reader import InfoConfReader
24+ 
25+NAMESPACE = 'common_func.trace_view_manager'
26+ 
27+ 
28+class TestTraceViewManager(unittest.TestCase):
29+ 
30+ def setUp(self):
31+ """初始化测试环境"""
32+ self.PID_OFFSET = TraceViewManager.PID_OFFSET
33+ self.INDEX_OFFSET = TraceViewManager.INDEX_OFFSET
34+ self.HOST_ID_FOR_PID = TraceViewManager.HOST_ID_FOR_PID
35+ InfoConfReader()._info_json = {"pid": 111, "devices": "2"}
36+ 
37+ def tearDown(self):
38+ InfoConfReader()._info_json.clear()
39+ 
40+ def _create_layer_info(self, general_layer, sort_index=0):
41+ """创建 LayerInfo 测试对象"""
42+ return TraceViewHeaderConstant.LayerInfo(
43+ component_layer=TraceViewHeaderConstant.COMPONENT_LAYER_CANN,
44+ general_layer=general_layer,
45+ sort_index=sort_index
46+ )
47+ 
48+ def test_get_format_pid_with_dpu_layer(self):
49+ """测试 DPU 层的 format_pid 计算"""
50+ layer_info = self._create_layer_info(
51+ general_layer=TraceViewHeaderConstant.GENERAL_LAYER_DPU,
52+ sort_index=5
53+ )
54+ 
55+ # pid=1 会被用作 device_id,然后 pid 被重新赋值为 11
56+ result = TraceViewManager.get_format_pid(pid=1, layer_info=layer_info)
57+ 
58+ # format_pid = (111 << 22) | (5 << 5) | 1
59+ expected = (111 << self.PID_OFFSET) | (5 << self.INDEX_OFFSET) | 1
60+ self.assertEqual(result, expected)
61+ 
62+ def test_get_format_pid_with_cpu_layer(self):
63+ """测试 CPU 层的 format_pid 计算"""
64+ layer_info = self._create_layer_info(
65+ general_layer=TraceViewHeaderConstant.GENERAL_LAYER_CPU,
66+ sort_index=10
67+ )
68+ 
69+ # CPU 层使用 HOST_ID_FOR_PID 作为 device_id
70+ result = TraceViewManager.get_format_pid(pid=200, layer_info=layer_info)
71+ 
72+ # format_pid = (200 << 22) | (10 << 5) | HOST_ID_FOR_PID
73+ expected = (200 << self.PID_OFFSET) | (10 << self.INDEX_OFFSET) | self.HOST_ID_FOR_PID
74+ self.assertEqual(result, expected)
75+ 
76+ def test_get_format_pid_with_invalid_device_id(self):
77+ """测试无效 device_id 的情况"""
78+ layer_info = self._create_layer_info(
79+ general_layer='OTHER_LAYER', # 非 DPU、非 CPU
80+ sort_index=3
81+ )
82+ InfoConfReader()._info_json = {"pid": 111, "devices": "kk"}
83+ result = TraceViewManager.get_format_pid(pid=150, layer_info=layer_info)
84+ 
85+ # 无效 device_id 时使用 HOST_ID_FOR_PID
86+ expected = (150 << self.PID_OFFSET) | (3 << self.INDEX_OFFSET) | self.HOST_ID_FOR_PID
87+ self.assertEqual(result, expected)
88+ 
89+ def test_get_format_pid_with_valid_device_id(self):
90+ """测试有效 device_id 的情况"""
91+ layer_info = self._create_layer_info(
92+ general_layer='OTHER_LAYER',
93+ sort_index=7
94+ )
95+ 
96+ result = TraceViewManager.get_format_pid(pid=300, layer_info=layer_info)
97+ 
98+ # format_pid = (300 << 22) | (7 << 5) | 2
99+ expected = (300 << self.PID_OFFSET) | (7 << self.INDEX_OFFSET) | 2
100+ self.assertEqual(result, expected)
101+ 
102+ def test_get_format_pid_with_zero_sort_index(self):
103+ """测试 sort_index 为 0 的情况"""
104+ layer_info = self._create_layer_info(
105+ general_layer='OTHER_LAYER',
106+ sort_index=0
107+ )
108+ 
109+ result = TraceViewManager.get_format_pid(pid=50, layer_info=layer_info)
110+ 
111+ expected = (50 << self.PID_OFFSET) | (0 << self.INDEX_OFFSET) | 2
112+ self.assertEqual(result, expected)
113+ 
114+ def test_get_format_pid_bit_structure(self):
115+ """验证位结构正确性"""
116+ layer_info = self._create_layer_info(
117+ general_layer='OTHER_LAYER',
118+ sort_index=15
119+ )
120+ 
121+ test_pid = 1000
122+ result = TraceViewManager.get_format_pid(pid=test_pid, layer_info=layer_info)
123+ 
124+ # 验证各个字段的提取
125+ extracted_device_id = result & 0x1F # 低 5 位
126+ extracted_sort_index = (result >> self.INDEX_OFFSET) & 0x1F # 中间 5 位
127+ extracted_pid = result >> self.PID_OFFSET # 高 22 位
128+ 
129+ self.assertEqual(extracted_device_id, 2)
130+ self.assertEqual(extracted_sort_index, 15)
131+ self.assertEqual(extracted_pid, test_pid)
132+ 
133+ def test_get_format_pid_dpu_layer_preserves_original_pid_as_device_id(self):
134+ """测试 DPU 层中原始 pid 被用作 device_id"""
135+ layer_info = self._create_layer_info(
136+ general_layer=TraceViewHeaderConstant.GENERAL_LAYER_DPU,
137+ sort_index=1
138+ )
139+ 
140+ original_pid = 7
141+ result = TraceViewManager.get_format_pid(pid=original_pid, layer_info=layer_info)
142+ 
143+ # 验证 device_id 是原始的 pid
144+ extracted_device_id = result & 0x1F
145+ self.assertEqual(extracted_device_id, original_pid)
146+ 
147+ # 验证 pid 被替换为 get_json_pid_data 的返回值
148+ extracted_pid = result >> self.PID_OFFSET
149+ self.assertEqual(extracted_pid, 111)
150+ 
151+ def test_get_format_pid_string_device_id_conversion(self):
152+ """测试字符串 device_id 转换为整数"""
153+ layer_info = self._create_layer_info(
154+ general_layer='OTHER_LAYER',
155+ sort_index=2
156+ )
157+ 
158+ result = TraceViewManager.get_format_pid(pid=100, layer_info=layer_info)
159+ 
160+ extracted_device_id = result & 0x1F
161+ self.assertEqual(extracted_device_id, 2)
162+ self.assertIsInstance(extracted_device_id, int)
163+