Pull Request已成功合入, 合并人@ascend-robot
(感谢 yuht9 的贡献)变更摘要
本次 PR 新增了 ExternalStream 类,作为 torch_npu.npu.Stream 的子类,用于包装外部库创建的 aclrtStream 句柄,使 torch_npu 能够在该流上 launch 算子,实现多库之间的数据交换。该变更同时在 C++ 层增加了对 stream_ptr 参数的构造支持,并通过 Python 层的大量文档说明了该类不支持的操作场景(如同步、查询、事件记录/等待、图捕获等),原因是外部流不在 torch_npu 内部的 AsyncTaskQueue 管理范围内。
主要改动
- 新增
ExternalStream类:在torch_npu/npu/streams.py中定义ExternalStream(Stream),其__new__方法接收stream_ptr(外部aclrtStream的整数值)和可选的device参数,在指定设备上下文中调用父类构造,并包含详细的不支持场景文档说明。 - C++ 层支持外部流构造:在
torch_npu/csrc/npu/Stream.cpp的THNPStream_pynew中增加对stream_ptr的处理逻辑——当传入stream_ptr时,校验priority和is_sync_launch必须保持默认值 0,然后调用c10_npu::getStreamFromExternal而不是从内部池获取流。 - 模块导出更新:在
torch_npu/npu/__init__.py中将ExternalStream加入__all__列表,并从.streams模块中导入,使其成为torch_npu.npu的公开 API。 - 新增测试用例:在
test/npu/test_stream.py中新增TestExternalStream测试类,覆盖外部流的创建、设为当前流、算子执行、相同指针对象相等性、isinstance检查,以及synchronize()和query()应抛出RuntimeError的限制验证。


代码审查
审查总结
- P0: 0
- P1: 0
- P2: 0
- P3: 1
各文件审查结果:
| 文件 | 结果 |
|---|---|
test/npu/test_stream.py |
无问题 |
torch_npu/csrc/npu/Stream.cpp |
无问题 |
torch_npu/npu/__init__.py |
无问题 |
torch_npu/npu/streams.py |
1 个 P3 建议(__repr__ 类名显示) |
整体风险判断:低。该变更逻辑正确:C++ 层三元表达式优先级合理,stream_ptr 校验完整,Python 层通过 ExternalStream.__new__ → Stream.__new__ → C 层的调用链正确传递参数,所有文档中列出的不支持场景在 C++ 层均有 checkNotExternalStream 守卫。测试覆盖了创建、设为当前流、算子执行、相等性、类型检查及 synchronize/query 限制。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 0 |
| 🟡 建议 | 1 |
💬 仅评论


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-Ascend/pytorch | ✅ liujunzhu, hbhu_bin (2/2) | ✅ liujunzhu (1/1) |
| test | ✅ hbhu_bin, liujunzhu (2/2) | ✅ liujunzhu (1/1) |
| torch_npu/npu | ✅ liujunzhu, hbhu_bin (2/2) | ✅ liujunzhu (1/1) |
💡 Tip:
- Committer can comment
/approveor/lgtm- Commenting
/approveimplies both code review (lgtm) and intent to merge (approve)
CLA Signature Pass
yuht9, thanks for your pull request. All authors of the commits have signed the CLA. 👍


当前仓库存在以下 保护分支 :
| Protected Branch | Version | Release |
|---|---|---|
| master | ||
| v2.12.0 | ||
| v2.10.0 | ||
| v2.9.0 | ||
| v2.7.1 | ||
| v2.11.0 | ||
| v2.7.1-26.1.0 | ||
| v2.12.0-26.1.0 | ||
| v2.11.0-26.1.0 | ||
| v2.10.0-26.1.0 | ||
| v2.9.0-26.1.0 | ||
| ci-test |
评论 /sync <branch1> <branch2> ... 可将当前 PR 修改同步到其它分支(创建同步 PR):
a) 如果当前 PR 是 Open 状态,同步操作将延迟到 PR 被合并时执行
b) 如果当前 PR 已经 Merged,将立即执行同步操作
注意:
- /sync 命令可以指定同步到多个分支,仅最后一个 /sync 命令生效
- 如果创建的同步 PR 不正确,可通过向同步 PR 的源分支提交轻量级 PR 完善,或使用 /close 命令关闭


ascend docs pipeline is running...


✅ 跳过 docs ci 检查,没有需要检查的文档文件


| 阶段 | 任务名 | 状态 | 详情 |
|---|---|---|---|
| 编译构建 | Build_X86 | ✅ | >>> |
| Build_ARM | ✅ | >>> | |
| Build_LibTorch_x86 | ✅ | >>> | |
| Build_LibTorch_ARM | ✅ | >>> | |
| Build_X86_torchair | 🛑 | >>> | |
| Build_ARM_torchair | 🛑 | >>> | |
| patch_test | 🛑 | >>> | |
| 恶意代码检查 | Antipoison | ✅ | >>> |
| 编码安全与规范检查 | CodeCheck | ✅ | >>> |
| check_error | ✅ | >>> | |
| CodeCheck_lintrunner | ✅ | >>> | |
| 开源片段检查 | SCA | ✅ | >>> |
| 开发者测试 | UT_ARM_A3_Part_01 | 🛑 | >>> |
| UT_ARM_A3_Part_02 | 🛑 | >>> | |
| UT_ARM_A2_Part_01 | ✅ | >>> | |
| UT_ARM_A2_Part_02 | ✅ | >>> | |
| UT_ARM_A2_Part_03 | ✅ | >>> | |
| UT_inductor_Part_01 | 🛑 | >>> | |
| UT_inductor_Part_02 | 🛑 | >>> | |
| UT_inductor_Part_03 | 🛑 | >>> | |
| UT_inductor_Part_04 | 🛑 | >>> | |
| UT_DIST_ARM_Part_01 | 🛑 | >>> | |
| UT_DIST_ARM_Part_02 | 🛑 | >>> | |
| UT_DIST_ARM_Part_03 | 🛑 | >>> | |
| UT_DIST_ARM_Part_04 | 🛑 | >>> | |
| UT_ARM_A2_Select_Part_01 | ✅ | >>> | |
| UT_ARM_A2_Select_Part_02 | ✅ | >>> | |
| 流水线 | PR-pipeline_pytorch | ✅ | >>> |
- compile、compile_inductor、compile_torchair : 运行流水线
- retry : 重试流水线所有失败子任务
- retry <任务名> : 仅重试指定失败子任务
- stop : 停止流水线


🟡 Medium Priority
changed line → affected behavior/contract → failure mode → suggested fix
问题链:
ExternalStream.__new__(streams.py:174-176)接受 stream_ptr 参数并透传至 C++ 构造函数 THNPStream_pynew(Stream.cpp:29),其中 stream_ptr 被声明为 uint64_t stream_ptr = 0。
当用户传入 stream_ptr=0(例如未初始化的 c_void_p 值)时:
而 getStreamFromExternal 内部虽有空指针校验(NPUStream.cpp:486:TORCH_CHECK(stream != nullptr, ...)),但因三元表达式已将 stream_ptr=0 过滤,该校验永远不会被触发。
失效模式: 用户显式构造 ExternalStream(0) 期望得到一个包装外部流的对象或收到明确错误,结果却静默得到一个普通池流,且该流的 stream_id 类型为 NORMAL/HIGH 而非 EXT,后续调用 synchronize() / query() 不会触发预期的 RuntimeError(测试 test_external_stream_synchronize_restriction / test_external_stream_query_restriction 专门验证了对真正外部流应抛错)。这在多库交互场景下可能导致难以排查的行为异常。
建议:在 ExternalStream.new 开头增加 stream_ptr 非零校验,提前以明确的 ValueError 拒绝零值指针,避免静默回退为普通池流。
|
176 | + def __new__(cls, stream_ptr, device=None, **kwargs): |
|
177 | + if not stream_ptr: |
|
178 | + raise ValueError("stream_ptr must be a non-zero integer for ExternalStream") |
|
179 | + with torch_npu.npu.device(device): |
| 176
180 | return super().__new__(cls, stream_ptr=stream_ptr, **kwargs) |


ascend docs pipeline is running...


✅ 跳过 docs ci 检查,没有需要检查的文档文件


ascend docs pipeline is running...


✅ 跳过 docs ci 检查,没有需要检查的文档文件


| 阶段 | 任务名 | 状态 | 详情 |
|---|---|---|---|
| 编译构建 | Build_X86 | ✅ | >>> |
| Build_ARM | ✅ | >>> | |
| Build_LibTorch_x86 | ✅ | >>> | |
| Build_LibTorch_ARM | ✅ | >>> | |
| Build_X86_torchair | 🛑 | >>> | |
| Build_ARM_torchair | 🛑 | >>> | |
| patch_test | 🛑 | >>> | |
| 恶意代码检查 | Antipoison | ✅ | >>> |
| 编码安全与规范检查 | CodeCheck | ✅ | >>> |
| check_error | ✅ | >>> | |
| CodeCheck_lintrunner | ✅ | >>> | |
| 开源片段检查 | SCA | ✅ | >>> |
| 开发者测试 | UT_ARM_A3_Part_01 | 🛑 | >>> |
| UT_ARM_A3_Part_02 | 🛑 | >>> | |
| UT_ARM_A2_Part_01 | ✅ | >>> | |
| UT_ARM_A2_Part_02 | ✅ | >>> | |
| UT_ARM_A2_Part_03 | ✅ | >>> | |
| UT_inductor_Part_01 | 🛑 | >>> | |
| UT_inductor_Part_02 | 🛑 | >>> | |
| UT_inductor_Part_03 | 🛑 | >>> | |
| UT_inductor_Part_04 | 🛑 | >>> | |
| UT_DIST_ARM_Part_01 | 🛑 | >>> | |
| UT_DIST_ARM_Part_02 | 🛑 | >>> | |
| UT_DIST_ARM_Part_03 | 🛑 | >>> | |
| UT_DIST_ARM_Part_04 | 🛑 | >>> | |
| UT_ARM_A2_Select_Part_01 | ✅ | >>> | |
| UT_ARM_A2_Select_Part_02 | ✅ | >>> | |
| 流水线 | PR-pipeline_pytorch | ✅ | >>> |
- compile、compile_inductor、compile_torchair : 运行流水线
- retry : 重试流水线所有失败子任务
- retry <任务名> : 仅重试指定失败子任务
- stop : 停止流水线


/approve


Pull Request 已合并或已关闭。
If you want to solve this problem, you can click here to do it in the FAQs.




【合入来源】
【修改方案】
ExternalStream是torch_npu.npu.Stream的子类,用于包装外部库创建的aclrtStream句柄,使 torch_npu 能在该流上 launch 算子,实现多库数据交换。类定义
class ExternalStream(Stream): def __new__(cls, stream_ptr, device=None, **kwargs): with torch_npu.npu.device(device): return super().__new__(cls, stream_ptr=stream_ptr, **kwargs)构造参数
stream_ptraclrtStream的整数值devicepriorityis_sync_launch【资料变更】
不涉及
【接口变更】
不涉及
【功能验证】
DT验证通过
【CheckList】