Pull Request已成功合入, 合并人@CANN-robot
(感谢 海阔天空 的贡献)变更摘要
本 PR 新增 ReformerLshBucketSort 自定义算子,用于在 Ascend 910B3 上精确替换 Reformer LSH attention 中的两次通用排序(sort_key_val 与 inverse-sort)。算子输入为"桶编号 + token 位置"编码的 int64 键值矩阵,通过基于桶计数排序的 Ascend C kernel 同时输出稳定排序后的 key、正向 permutation(sticker)和逆向 permutation(inverse)。该算子不改变 Reformer 模型结构与预测语义,在 B32/L336 形状下相对框架原生排序实现最高加速 62.47 倍,完整 ETTh1 测试集端到端延迟降低 56.21% 且预测指标完全一致。
主要改动
-
新增 Ascend C 内核实现:
reformer_lsh_bucket_sort_kernel.cpp实现了基于桶计数的稳定排序 kernel,按行并行执行"计数 → 前缀和 → 散射"三阶段,将通用排序替换为确定性桶排序,并同时产出sorted_keys、sticker和inverse三个输出张量。 -
新增 Host 侧算子定义与 Tiling:
reformer_lsh_bucket_sort_def.cpp注册了ReformerLshBucketSort算子类,声明一个int64ND 输入和三个同形状输出,以及sequence_length和total_buckets两个必选整型属性;reformer_lsh_bucket_sort_tiling.h定义了包含rows、total_length、sequence_length、total_buckets的 Tiling 数据结构,Host 端在reformer_lsh_bucket_sort_host.cpp中对输入形状和属性值域进行校验(total_buckets ≤ 4096,维度大小适配uint32/int32)。 -
新增 Python 适配器与守卫逻辑:
integration/adapter.py提供supports_custom()和dispatch()函数,严格校验输入 tensor 的 device、dtype(仅torch.int64)、contiguous 属性及形状/参数值域上限,不满足条件时自动回退到框架原生 fallback,确保非目标场景不受影响。 -
新增 CPU 参考实现与契约测试:
reference/reference.py提供了无依赖的纯 Python 参考实现,明确稳定排序契约(同桶内保持原始相对顺序)和 inverse 索引可逆性;tests/test_reference.py覆盖标准用例、边界值、随机稳定性验证和最小值校验。 -
新增独立构建 Gate 与性能证据:
run_packaged_gate.sh整合 msopgen 生成、源码替换、CMake 构建和 ACLNN smoke 测试的完整流水线;docs/evidence/目录下的 JSON 证据文件记录了 6 档形状的组件级速度提升(最高 62.47×)、B32/L336 模型级 68.11% 延迟降低及 ETTh1 完整测试集 2857 窗口的端到端结果。


代码审查
All major aspects have been checked. Now let me provide the closing summary.
审查结束 — 汇总
各文件审查结论
| 文件 | 结果 |
|---|---|
CMakeLists.txt |
无问题 |
README.md |
无问题 |
docs/algorithm.md |
无问题 |
docs/api_reference.md |
无问题 |
docs/benchmark.md |
无问题 |
docs/evidence/checkpoint_etth1.json |
无问题 |
docs/evidence/component_matrix.json |
无问题 |
docs/evidence/model_ablation.json |
无问题 |
docs/evidence/multistream.json |
无问题 |
docs/evidence/node202_gate_summary.json |
无问题 |
docs/test_report.md |
无问题 |
docs/upstream_dedup.md |
无问题 |
examples/test_aclnn_reformer_lsh_bucket_sort.cpp |
2 个 P2 + 1 个 P3 |
integration/adapter.py |
无问题 |
msopgen/reformer_lsh_bucket_sort_msopgen.json |
无问题 |
op_host/reformer_lsh_bucket_sort_def.cpp |
无问题 |
op_host/reformer_lsh_bucket_sort_host.cpp |
1 个 P3 |
op_host/reformer_lsh_bucket_sort_tiling.h |
无问题 |
op_kernel/reformer_lsh_bucket_sort_kernel.cpp |
无问题 |
reference/reference.py |
无问题 |
tests/CMakeLists.txt |
无问题 |
tests/benchmark_reformer_lsh_bucket_sort_aclnn.cpp |
无问题 |
tests/run_packaged_gate.sh |
无问题 |
tests/test_adapter.py |
无问题 |
tests/test_reference.py |
无问题 |
tests/ut/CMakeLists.txt |
无问题 |
tests/ut/op_kernel/CMakeLists.txt |
无问题 |
tests/ut/op_kernel/test_reformer_lsh_bucket_sort.cpp |
无问题 |
按优先级统计
- P0: 0
- P1: 0
- P2: 2(设备内存泄漏、未检查空 tensor 指针,均位于示例代码)
- P3: 2(workspace 错误路径泄漏、InferShape 缺少空指针检查)
整体风险判断
低风险。 核心算子逻辑(kernel、tiling、host 校验)经审查未发现正确性问题:32 位乘法链首已正确提升到 64 位、边界条件在 host 侧有完整的参数校验(拒绝 0 值、超界 shape、非法桶数)、计数排序的稳定性实现正确、GM 偏移计算均在 uint64 域内。发现的问题全部集中在示例代码 test_aclnn_reformer_lsh_bucket_sort.cpp 的错误处理路径(资源泄漏与空指针),以及 InferShape 函数的一处防御性编码不一致,均不影响算子的生产正确性与性能。建议在合入前修复示例代码中的两个 P2 资源管理问题,避免该示例被其他算子开发者复制时扩散不良模式。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 0 |
| 🟡 建议 | 2 |
💬 仅评论


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
⚠️ This PR does not yet meet the following requirements:lgtm (requires ≥ 2 person(s) per module)、approve (requires ≥ 1 person(s) per module)
Module Approval Details
| module | lgtm status | approve status |
|---|---|---|
| repo-cann/mat-chem-sim-pred | ❌ (0/2)(You can also ask: 李姝漫, 赵俊, 高菲, 黄剑兴, 张强豪) | ❌ (0/1)(You can also ask: 张玉橙, 高梓博, 刘达林, 张强豪, 李姝漫) |
💡 Tip:
- Committer can comment
/approveor/lgtm- Commenting
/approveimplies both code review (lgtm) and intent to merge (approve)
CLA Signature Pass
haikuo, thanks for your pull request. All authors of the commits have signed the CLA. 👍


/compile


🟡 Medium Priority
changed line 101-104 → MakeTensor 内部调用 aclCreateTensor,分配失败时返回 nullptr。四路 MakeTensor 返回值(keys、sorted、sticker、inverse)均未做空检查,直接传入 aclnnReformerLshBucketSortGetWorkspaceSize。若任一 tensor 为 null,ACLNN API 将收到空指针,行为未定义,大概率触发段错误或 AIC error。
建议:在每个 MakeTensor 调用后增加空指针检查,若返回 nullptr 则释放已分配资源(dKeys/dSorted/dSticker/dInverse 及已创建的 tensor)后返回错误码。


🟡 Medium Priority
changed line 96-100 → 当 CopyToDevice(&dKeys, hKeys) 成功(dKeys 已分配),但后续 AllocateOutput<int64_t>(&dSorted, 8) 或更后面的分配失败时,短路求值使整体条件为 true,直接 return 1,dKeys(以及可能已成功分配的 dSorted、dSticker)泄漏。此外,CopyToDevice 内部也存在同类泄漏:若 aclrtMalloc 成功但 aclrtMemcpy 失败,已分配内存同样泄漏。
建议:在 return 前释放已成功分配的资源。将分配步骤拆分为独立的 if 判断,每个失败分支释放已分配的资源;或使用 RAII 包装 aclrtMalloc/aclrtFree。


/lgtm


/approve


/lgtm


The following label is not ready.
ci-pipeline-passed: The ci-pipeline-passed label is expired as added over 72 hours. Please use /compile to recompile.


compile


compile


变更概述
本 MR 新增
ReformerLshBucketSort,用于精确替换 Reformer LSH attention中的两次通用排序。算子输入确定性的“桶编号 + token 位置”编码,同时输出:
该算子替换 reformer-pytorch 1.4.4 中由 TSLib Reformer encoder 调用的
sort_key_val与 inverse-sort 热点。它不替换 attention score、softmax、value aggregation 或预测头,不改变 Reformer 的模型结构和预测语义。
Native、TorchAir 与自定义算子三路审计
当前 TSLib 源码在 hash 路径中创建 CPU
torch.Generator,会阻断官方模型的fullgraph 捕获。TorchAir 审计恢复了上游
torch.randn(..., device=npu)的NPU 随机旋转表达,不改变 hashing、sorting、inverse sorting、attention、
模型权重或输入。
六档兼容 TorchAir 图均能正确执行,观察到的最大图模式/reference 误差为
3.40e-5。TorchAir 在最小 B4/L96 档占优,但没有吸收本算子所针对的B32/L336 排序热点。
算子阶段与完整测试集证据
37.2931 -> 0.6023 ms,延迟降低 98.38%,加速 61.92 倍,三个输出均逐元素一致。
55.5278 ms、TorchAir99.7328 ms、自定义算子
17.5769 ms,相对最快 Native 降低 68.35%。55.1197 -> 17.5769 ms,延迟降低 68.11%。1558.82 ms-> 自定义算子682.56 ms,延迟降低 56.21%,预测指标保持不变。完整测试集 headline 使用 Native 作为基线,因为同形状 TorchAir 图在替换前
比 Native 慢 79.62%。同轮三路 68.35% 与独立 gate 68.11% 来自两次独立
测试口径,不进行混算。
对外接口与验证
aclnnReformerLshBucketSortGetWorkspaceSize;aclnnReformerLshBucketSort。交付件包含 Host API、Ascend C kernel、稳定顺序与 inverse 索引契约测试、
独立构建、ACL smoke、输出所有权测试、文档、形状矩阵证据、checkpoint 模型
E2E 以及完整测试集性能证据。