Pull Request已成功合入, 合并人@CANN-robot
(感谢 丛吉钰 的贡献)Thanks for your pull-request.
The full list of commands accepted by me can be found at here。
You can get sig-info at here
PR Approval Progress
✅ Congratulations! All modules have met the lgtm and approve requirements.
Module Approval Details
| module | lgtm status | approve status |
|---|---|---|
| repo-cann/ops-math | ✅ songkai111, wangrui_ (2/2) | ✅ songkai111 (1/1) |
💡 Tip:
- Committer can comment
/approveor/lgtm- Commenting
/approveimplies both code review (lgtm) and intent to merge (approve)


🔵 source code change are detected, tasks labels is removed in this pull request!


compile


问题/功能描述
本次PR旨在解决深度学习算子编译流水线中缺乏细粒度性能监控的问题。通过新增一个构建耗时分析工具,实现对算子编译过程的时间消耗与产物大小的自动化统计与记录,为后续的性能优化和资源评估提供数据支持。
修改方案描述
核心修改包括新增一个Python分析脚本和增强现有构建脚本。首先,新增的analyze_ops_time.py脚本能够遍历构建日志,解析每个算子编译任务的起止时间、耗时、状态及产物大小,并生成结构化的CSV报告。其次,修改了构建脚本build_binary_op_exe_task.sh,在日志中标准化地添加了时间戳标记,为分析脚本提供输入。同时,移除了其他脚本中冗余的日志包装逻辑,确保日志格式统一。


流水线任务触发成功 [流水线指导]
任务链接 [eebac5e81f7c43f2b88225b66acd0b39]
| 任务名称 | 状态 | 日志 | 下载链接 |
|---|---|---|---|
| codecheck | ❌ FAILED | >>>>> | |
| SCA | ✅ SUCCESS | >>>>> | |
| anti_virus | ✅ SUCCESS | >>>>> | |
| Check_Pr | ✅ SUCCESS | >>>>> | |
| Compile_Ascend_X86 | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_X86_mobile_station | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_ARM | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_X86_experimental | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_ARM_experimental | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_single | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_X86_A5 | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_ARM_A5 | ✅ SUCCESS | >>>>> | >>>>> |
| API_Check | ✅ SUCCESS | >>>>> | |
| UT_Test | ⚪ ABORTED | ||
| UT_Test_experimental | ⚪ ABORTED | ||
| Smoke_A900 | ⚪ ABORTED | >>>>> | >>>>> |
[2026-02-03 19:47:38] CI执行失败


代码逻辑和结构: existing_ops变量被计算但从未使用。在第63行计算了existing_ops集合,但在后续代码中没有任何地方引用这个变量。这可能是未完成的代码或者遗留的调试代码。
问题类型: 代码逻辑和结构
文件路径: scripts/ci/analyze_ops_time.py
行号: 62
问题代码:
else:
existing_ops = {d.name for d in ops_root.iterdir() if d.is_dir()}
修改建议:
如果existing_ops确实不需要,应该删除这行代码以避免混淆。如果需要使用,应该明确其用途,比如用于验证日志文件对应的op目录是否存在,或者用于过滤无效的op记录。
此评论由代码审查工具自动生成


代码逻辑和结构: op名称的特殊处理逻辑存在问题。代码在第113-120行修改了op变量的值,但这会影响后续的统计。修改后的op变量用于构建obj_dir路径,但统计字典all_stats[soc_name]中的键仍然是原始的op名称。这可能导致obj_dir路径构建错误,因为修改后的op名称可能与原始op名称不匹配。
问题类型: 代码逻辑和结构
文件路径: scripts/ci/analyze_ops_time.py
行号: 113
问题代码:
if not stats['obj_dir_checked']:
stats['obj_dir_checked'] = True
if op == "conv3dv2":
op = "conv3d_v2"
elif op == "conv2dv2":
op = "conv2d_v2"
elif op == "dynamic_rnn_v2":
op = "dynamic_rnnv2"
obj_dir = ops_root / op
修改建议:
应该使用一个临时变量来存储修改后的op名称,而不是直接修改op变量。例如:processed_op = op
if op == "conv3dv2": processed_op = "conv3d_v2"
...
obj_dir = ops_root / processed_op
此评论由代码审查工具自动生成


性能问题: duration_s的计算可能产生错误结果。代码使用earliest_start和latest_end的时间差来计算总时长,但这两个时间分别来自不同日志文件的最早开始时间和最晚结束时间。如果多个op实例是并行执行的,这种计算方式会高估实际耗时。
问题类型: 性能问题
文件路径: scripts/ci/analyze_ops_time.py
行号: 140
问题代码:
if success_count > 0:
duration_s = int((data['latest_end'] - data['earliest_start']).total_seconds())
修改建议:
应该重新考虑统计指标的定义。如果目标是统计每个op的总构建时间,应该累加每个实例的执行时间(从exe_time中获取)。如果目标是统计整个构建过程的时间跨度,当前的实现可能合适,但需要明确注释说明。
此评论由代码审查工具自动生成


代码逻辑和结构: 排序逻辑的注释与实现不完全一致。注释说"按照有效时长排序(有时长的在前),然后按照时长降序排序",但实际的排序键是(x['duration(s)'] != -1, x['duration(s)']),reverse=True。这意味着:1)duration(s) != -1的排在前面(True > False),2)然后按duration(s)降序排序。这与注释描述一致,但reverse=True会影响两个排序条件。
问题类型: 代码逻辑和结构
文件路径: scripts/ci/analyze_ops_time.py
行号: 153
问题代码:
csv_rows.sort(key=lambda x: (x['duration(s)'] != -1, x['duration(s)']), reverse=True)
修改建议:
虽然当前实现可能正确,但建议使用更清晰的排序方式:csv_rows.sort(key=lambda x: (x['duration(s)'] == -1, -x['duration(s)'] if x['duration(s)'] != -1 else 0))。这样不需要reverse=True,逻辑更清晰。同时确保注释准确描述排序行为。
此评论由代码审查工具自动生成


可维护性和扩展性: 硬编码的op名称映射缺乏可扩展性。代码在第115-120行硬编码了三个op名称的特殊处理(conv3dv2、conv2dv2、dynamic_rnn_v2)。如果需要添加更多特殊映射,需要修改代码。这种硬编码方式降低了代码的可维护性。
问题类型: 可维护性和扩展性
文件路径: scripts/ci/analyze_ops_time.py
行号: 115
问题代码:
if op == "conv3dv2":
op = "conv3d_v2"
elif op == "conv2dv2":
op = "conv2d_v2"
elif op == "dynamic_rnn_v2":
op = "dynamic_rnnv2"
修改建议:
建议将op名称映射提取到配置文件或字典常量中。例如:OP_NAME_MAPPING = {"conv3dv2": "conv3d_v2", "conv2dv2": "conv2d_v2", "dynamic_rnn_v2": "dynamic_rnnv2"},然后使用processed_op = OP_NAME_MAPPING.get(op, op)。这样新增映射时只需修改配置,不需要修改核心逻辑。
此评论由代码审查工具自动生成


错误处理与异常管理: 文件过滤条件存在逻辑问题。第68行的条件判断使用or连接两个条件:1)log_file.suffix.lower() == '.log',2)log_file.name.startswith('.')。这意味着只要文件名以点开头,即使后缀不是.log也会被跳过。但实际意图应该是:跳过非.log文件,同时跳过隐藏文件(以点开头的文件)。当前使用or会导致一些.log文件被错误跳过。
问题类型: 错误处理与异常管理
文件路径: scripts/ci/analyze_ops_time.py
行号: 68
问题代码:
if not log_file.suffix.lower() == '.log' or log_file.name.startswith('.'):
continue
修改建议:
应该使用and逻辑:if not (log_file.suffix.lower() == '.log' and not log_file.name.startswith('.')): continue。或者更清晰地写成两个单独的条件:if log_file.suffix.lower() != '.log': continue
if log_file.name.startswith('.'): continue
此评论由代码审查工具自动生成


🔵 source code change are detected, tasks labels is removed in this pull request!


compile


流水线任务触发成功 [流水线指导]
任务链接 [00e0b3dc833a467fa027394b2f05c9ee]
| 任务名称 | 状态 | 日志 | 下载链接 |
|---|---|---|---|
| codecheck | ❌ FAILED | >>>>> | |
| SCA | ✅ SUCCESS | >>>>> | |
| anti_virus | ✅ SUCCESS | >>>>> | |
| Check_Pr | ✅ SUCCESS | >>>>> | |
| Compile_Ascend_X86 | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_X86_mobile_station | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_ARM | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_X86_experimental | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_ARM_experimental | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_single | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_X86_A5 | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_ARM_A5 | ✅ SUCCESS | >>>>> | >>>>> |
| API_Check | ✅ SUCCESS | >>>>> | |
| UT_Test | ⚪ ABORTED | ||
| UT_Test_experimental | ⚪ ABORTED | ||
| Smoke_A900 | ⚪ ABORTED | >>>>> | >>>>> |
[2026-02-03 20:17:48] CI执行失败


compile


流水线任务触发成功 [流水线指导]
任务链接 [f1f88842bed049edace20ae4416ddde0]
| 任务名称 | 状态 | 日志 | 下载链接 |
|---|---|---|---|
| codecheck | ✅ SUCCESS | >>>>> | |
| SCA | ✅ SUCCESS | >>>>> | |
| anti_virus | ✅ SUCCESS | >>>>> | |
| Check_Pr | ✅ SUCCESS | >>>>> | |
| Compile_Ascend_X86 | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_X86_mobile_station | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_ARM | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_X86_experimental | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_ARM_experimental | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_single | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_X86_A5 | ✅ SUCCESS | >>>>> | >>>>> |
| Compile_Ascend_ARM_A5 | ✅ SUCCESS | >>>>> | >>>>> |
| API_Check | ✅ SUCCESS | >>>>> | |
| UT_Test | ✅ SUCCESS | ||
| UT_Test_experimental | ✅ SUCCESS | ||
| Smoke_A900 | ✅ SUCCESS | >>>>> | >>>>> |
| Smoke_harmony-infer | ✅ SUCCESS | >>>>> |
[2026-02-04 11:02:39] CI执行结束


/approve


Review Guide
This Pull-Request Passes Review.
Committers who wrote a comment of /approve are: songkai111.
Reviewers who wrote a comment of /lgtm are: wangrui_, songkai111.


描述
在所有算子编译结束后,统计kernel耗时、.o总大小、应编译.o的数量
使用方式
在ops-math目录下执行python3 scripts/ci/analyze_ops_time.py,会在build目录下生成ops_cost_{soc}.csv统计文件
关联的Issue
#633
测试
每列具体信息为算子名、算子耗时、所有.o文件的大小、应编译.o的数量
文档更新
类型标签