Pull Request已成功合入, 合并人@ascend-robot
(感谢 Flipped 的贡献)变更摘要
本次变更为 v2.11.0 新增 test_upstream/test/test_cuda.py.patch,将 PyTorch 官方 test_graphsafe_set_get_rng_state 用例(覆盖 torch.Generator.clone_state、graphsafe_get_state、graphsafe_set_state 等功能)从 CUDA 环境适配到 NPU 环境,使该测试可在 NPU 设备上验证随机数生成器状态克隆与图捕获场景下的一致性。
主要改动
- 新增 NPU 适配的 patch 文件:创建
test_upstream/test/test_cuda.py.patch,对原始test/test_cuda.py进行 88 行新增的补丁,将test_graphsafe_set_get_rng_state测试用例从 CUDA 专属接口全面替换为 NPU 对应接口。 - 设备与接口替换(cuda → npu):将所有
device="cuda"替换为device="npu",并将torch.cuda.CUDAGraph()、torch.cuda.Stream()、torch.cuda.default_generators、torch.cuda.stream()、torch.cuda.current_stream()等 CUDA API 对应替换为torch.npu.NPUGraph()、torch.npu.Stream()、torch.npu.default_generators、torch.npu.stream()、torch.npu.current_stream()等 NPU API。 - 导入模块与兼容性处理:新增
import torch_npu和from torch_npu.contrib import transfer_to_npu,并通过 monkey-patch 方式处理torch.cuda.get_device_capability返回None时的兼容性问题(将其替换为返回(0, 0)的 lambda)。 - 测试条件与装饰器调整:将跳过条件从检查
TEST_CUDA_GRAPH改为not torch.npu.is_available(),并新增@skipCUDAMemoryLeakCheckIf(True)和@skipCUDANonDefaultStreamIf(True)装饰器,确保测试仅在 NPU 可用时执行。 - NPU Generator 初始化:在获取
torch.npu.default_generators[0]之前新增torch.rand(1, device="npu")调用,确保 NPU 默认随机数生成器在使用前已被正确初始化。


代码审查
经过仔细审查整个 patch 文件,我对所有修改行逐一进行了分析:
-
import torch_npu与from torch_npu.contrib import transfer_to_npu(第 9-10 行):transfer_to_npu是一个具有 import 时副作用的模块,会 patchtorch.cuda系列函数以重定向到 NPU——这是 Ascend NPU 适配的标准模式,并非无用导入。 -
get_device_capability的 monkey-patch(第 15-16 行):在无 CUDA 设备时作为安全兜底,防止文件中其他 CUDA 相关代码因get_device_capability()返回 None 而崩溃。由于transfer_to_npu已在此前被导入并 patch 了该函数,此 monkey-patch 仅在极端情况下触发,属防御性编程。 -
@skipCUDAMemoryLeakCheckIf(True)与@skipCUDANonDefaultStreamIf(True)(第 24-25 行):这两个装饰器在 NPU 测试中广泛使用(test/test_npu.py等多处均有相同模式),用于跳过 NPU 上可能产生的误报 leak 检查和非默认流检查。 -
skip 条件(第 28 行):从
TEST_CUDA_GRAPH改为not torch.npu.is_available(),正确适配 NPU 可用性判断。 -
所有
device="cuda"→device="npu"及torch.cuda.*→torch.npu.*的替换:NPU API 完全镜像 CUDA API,NPUGraph、Stream、default_generators、stream()、current_stream()等均存在于torch_npu中,经核实均有对应实现,替换正确。 -
新增
torch.rand(1, device="npu")(第 69 行):在访问default_generators[0]前初始化 NPU 上下文,是必要的初始化步骤。
审查结论
本次审查共发现 0 个问题。该 patch 是对上游 test/test_cuda.py::TestCuda.test_graphsafe_set_get_rng_state 用例的 NPU 适配,所有修改均遵循仓库中已有的 NPU 适配模式(与 test_futures.py.patch 和 test/test_npu.py 中的模式一致),代码变更正确、安全。
已审查文件:
test_upstream/test/test_cuda.py.patch— 无问题
整体风险评估:低风险。 该 patch 是标准的设备适配变更,不涉及业务逻辑修改,仅将 CUDA 专属 API 替换为 NPU 等价 API,且适配模式与仓库现有实践一致。
⚠️ 已识别出整体风险,但无法提取行内评论,请参考整体评估。


/approve




【合入来源】
issue:【社区任务】7月社区任务第三期-Ascend for PyTorch API 一致性开发(124) #3235
issue:[Usage]: torch.Generator.clone_state NPU一致性验证 #3476
【修改方案】
1. API基础功能及用例覆盖
torch.Generator.clone_state用于克隆当前Generator的随机数状态,返回一个新的Generator对象。克隆后的 Generator 应保持与原 Generator 克隆时一致的 RNG 状态,从而保证后续随机数生成结果可复现。PyTorch v2.11.0 官方社区中已存在
torch.Generator.clone_state相关用例,检索结果包括:其中本次适配的官方目标用例为:
该用例直接覆盖以下 Generator RNG 状态相关功能:
graphsafe_get_stateclone_stategraphsafe_set_state因此,本次无需新增自定义测试用例,只需适配现有 PyTorch 官方用例。
2. v2.11.0原有patch情况
v2.11.0 原本不存在:
因此,本次为 v2.11.0 新增:
原始官方用例中使用了 CUDA 专属接口和 CUDA 设备:
torch.Generator(device="cuda") torch.cuda.CUDAGraph() torch.cuda.Stream() torch.cuda.default_generators[0] torch.cuda.stream(s) torch.cuda.current_stream().wait_stream(s) torch.rand(..., device="cuda")在 NPU 环境下直接运行时,该用例会因 CUDA graph 条件不满足而跳过,无法覆盖
torch.Generator.clone_state在 NPU 上的行为。此外,在导入测试依赖时,
torch.cuda.get_device_capability()在 NPU 环境下可能返回None或触发兼容性告警,因此本次增加兼容处理,避免测试导入阶段受到 CUDA capability 判断逻辑影响。3. 本次修改内容
本次新增
test_upstream/test/test_cuda.py.patch,对test_graphsafe_set_get_rng_state进行 NPU 适配。主要修改如下:
import torch_npu from torch_npu.contrib import transfer_to_nputorch.cuda.get_device_capability()返回None时的兼容处理:if torch.cuda.get_device_capability() is None: torch.cuda.get_device_capability = lambda device=None: (0, 0) # noqa: E731torch.rand(..., device="npu")generator = torch.Generator(device="npu")g = torch.npu.NPUGraph() s = torch.npu.Stream() default_generator = torch.npu.default_generators[0]with torch.npu.stream(s):@unittest.skipIf( not torch.npu.is_available(), "NPU not available, skipping tests" )@skipCUDAMemoryLeakCheckIf(True) @skipCUDANonDefaultStreamIf(True)导入顺序说明
test/test_cuda.py中torch_npu/transfer_to_npu的导入位置属于初始化依赖例外。TestCuda类存在类级跳过条件:@unittest.skipIf(not TEST_CUDA, "CUDA not available, skipping tests") class TestCuda(TestCase):TEST_CUDA 来自 torch.testing._internal.common_cuda,会在模块导入阶段计算。若严格将 torch_npu / transfer_to_npu 放到所有 torch.testing 导入之后,NPU 环境下 TEST_CUDA 会提前计算为 False,导致目标用例 test_graphsafe_set_get_rng_state 被类级 skip,无法覆盖 torch.Generator.clone_state。
因此本 patch 保留 transfer_to_npu 在 common_cuda 导入前初始化。该处理不使用 try-except,不修改 TestCuda 类级 skip 条件,也不新增 NPU 专用测试类,仅用于保证官方目标用例能在 NPU 上真实执行。
本次只适配官方已有用例,不修改
torch.Generator.clone_state接口实现。本次适配的
test_graphsafe_set_get_rng_state已能覆盖torch.Generator.clone_state在 NPU Generator RNG 状态克隆场景下的核心行为。【资料变更】
已检查 master 分支
docs/zh/api/native_api资料目录,torch.Generator.clone_state为 PyTorch Generator 公开接口,非私有接口。该 API 属于 Generator 状态类 API,非计算类 API,与具体数据类型无关,限制与说明填写为-。根据 master 分支最新资料目录规则,
pytorch_2-9-0与pytorch_2-10-0目录已删除,本次不再补充;新增pytorch_2-13-0目录需要同步检查并刷新。资料补齐以 master 分支docs/zh/api/native_api当前实际存在的版本目录为准。资料补齐已在 master 分支单独提交 PR。本次未新增独立的
torch-Generator.md文件,而是在各版本已有torch.md的## Generators章节中补充clone_state()条目,位置放在set_state()之后,保持torch.Generator相关 API 统一维护在torch.md中。【接口变更】
不涉及。
本次仅适配 PyTorch 官方测试用例,不修改客户可见接口,不修改
torch.Generator.clone_state功能实现。【功能验证】
运行环境
将最终 patch 应用到干净的 PyTorch v2.11.0 工作树后,运行官方目标用例。
cd /workspace source /workspace/envs/torch-npu-2.11.0/bin/activate source /usr/local/Ascend/ascend-toolkit/set_env.sh unset PYTHONPATH export PYTHONPATH=/workspace/pytorch-v2.11.0/test export PYTHONNOUSERSITE=1 export PYTORCH_PRINT_REPRO_ON_FAILURE=0 python /workspace/pytorch-v2.11.0/test/test_cuda.py -v -k test_graphsafe_set_get_rng_state验证结果:
最终 patch 可以在干净工作树中正常应用,修改后的官方用例已在 NPU 上通过,可以覆盖
torch.Generator.clone_state的核心功能。【CheckList】