| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
test: add NPU coverage for symbolic_shapes APIs (issue #1614) Co-authored-by: zhangjiahao-2026<2332445379@qq.com> # message auto-generated for no-merge-commit merge: !36834 merge intern-1614-v2.10.0 into v2.10.0 test: add NPU coverage for symbolic_shapes APIs (issue #1614) Created-by: zhangjiahao-2026 Commit-by: zhangjiahao-2026 Merged-by: ascend-robot Description: # 【合入来源】 > **关联社区 issue:** https://gitcode.com/Ascend/pytorch/issues/1614 - [ ] 需求 - [ ] 问题单 - [x] issue/工单 - [ ] 重构优化 - [ ] 资料更新 # 【修改方案】 本次为 Torch-NPU API 一致性对齐任务(Issue #1614),针对 torch.fx.experimental.symbolic_shapes 下 5 个 API 补充/适配测试,**不涉及算子或 API 实现代码修改**(NPU 上与 PyTorch 2.10 行为一致)。 ## API 功能说明 torch.fx.experimental.symbolic_shapes 是 PyTorch FX 动态 shape 推导体系中的符号形状模块,负责在编译/导出过程中管理 SymInt/SymBool 约束、guard 生成及 shape 相等关系。本次验证的 5 个 API 均为纯 Python 层面的符号 shape 工具,与底层计算硬件无关。 - torch.fx.experimental.symbolic_shapes.DivideByKey:整除键类,用于在符号 shape 表达中表示对某个常量做 floor division(整除)的运算模式,可通过构造参数指定除数。 - torch.fx.experimental.symbolic_shapes.DivideByKey.get:DivideByKey 实例方法,对给定数值执行 floor division,即 value // divisor,返回整除结果。 - torch.fx.experimental.symbolic_shapes.EqualityConstraint:符号 shape 约束类,用于在 FX 图导出/动态 shape 推导中表达多个 shape 源之间的相等关系,包含 source_pairs、derived_equalities、phantom_symbols、relaxed_sources、warn_only 等字段。 - torch.fx.experimental.symbolic_shapes.has_free_symbols:判断给定对象(通常为 sympy 表达式)是否包含未被绑定的自由符号,用于区分常量表达式与含符号变量的动态 shape 表达式。 - torch.fx.experimental.symbolic_shapes.guard_size_oblivious:符号 shape guard 生成过程中的辅助函数,对布尔条件做 size-oblivious 处理,使其与具体 tensor size 解耦。 ## API 全名与测试覆盖场景 | 全名 API | 测试用例 | 覆盖场景 | |----------|----------|----------| | torch.fx.experimental.symbolic_shapes.DivideByKey | 自写 TestDivideByKeyAndEqualityConstraint::test_divide_by_key + 官方 test/export/test_export.py::test_unbacked_bindings_for_divisible_u_symint(patch) | 自写:构造 DivideByKey(4),验证 str(key) 为 ".__floordiv__(4)";官方:patch 注入 torch_npu 后复用 export 场景用例 | | torch.fx.experimental.symbolic_shapes.DivideByKey.get | 自写 TestDivideByKeyAndEqualityConstraint::test_divide_by_key_get | 构造 DivideByKey(4),调用 .get(17),验证返回 4 | | torch.fx.experimental.symbolic_shapes.EqualityConstraint | 自写 TestDivideByKeyAndEqualityConstraint::test_equality_constraint_init | 以空约束参数初始化(source_pairs=[],derived_equalities=[],phantom_symbols=[],relaxed_sources=set(),warn_only=False),验证 source_pairs、phantom_symbols 为空且 warn_only=False | | torch.fx.experimental.symbolic_shapes.has_free_symbols | 官方 test/test_dynamic_shapes.py(patch) | patch 注入 import torch_npu 后复用官方用例 | | torch.fx.experimental.symbolic_shapes.guard_size_oblivious | 官方 test/dynamo/test_misc.py(patch) | patch 注入 import torch_npu 后复用官方用例 | ## 具体改动 1. 在 test/fx/test_symbolic_shapes.py 新增 TestDivideByKeyAndEqualityConstraint 类,补充 3 个自写用例 - 使用 unittest + torch.testing._internal.common_utils.run_tests - 覆盖 API:DivideByKey、DivideByKey.get、EqualityConstraint - 用例均带 @unittest.skipUnless(torch.npu.is_available()) 2. 新增 test_upstream/test/test_dynamic_shapes.py.patch - 在 import torch 后增加 import torch_npu - 适配官方 has_free_symbols 用例 - **v2.10.0 注意:** 上游相对 v2.9.0 增加 import pytest,patch 按 v2.10.0 上下文单独生成 3. 新增 test_upstream/test/dynamo/test_misc.py.patch - 在 import torch 后增加 import torch_npu - 适配官方 guard_size_oblivious 用例 4. 新增 test_upstream/test/export/test_export.py.patch - 在 import torch 后增加 import torch_npu - 适配官方 test_unbacked_bindings_for_divisible_u_symint(断言含 DivideByKey) - **v2.10.0 注意:** 上游增加 import torch.fx.traceback as fx_traceback,不可复用 v2.9.0 patch 5. 上述 3 个 patch 已对 **v2.10.0** 上游文件执行 git apply --check,验证可应用。 # 【资料变更】 不涉及 # 【接口变更】 不涉及 # 【功能验证】 **测试环境:** torch 2.10.0 + torch_npu 2.10.0,torch.npu.is_available()==True **(1)自写用例** bash cd /tmp && python3 /data/pytorch/test/fx/test_symbolic_shapes.py \ TestDivideByKeyAndEqualityConstraint.test_divide_by_key \ TestDivideByKeyAndEqualityConstraint.test_divide_by_key_get \ TestDivideByKeyAndEqualityConstraint.test_equality_constraint_init \ 2>&1 | grep -vE "recording\.py|set_unbacked_var_to_val|E0626" | tail -10 结果:  **(2)5 API 快速验证** bash cd /tmp python -c " import torch import torch_npu from torch.fx.experimental.symbolic_shapes import ( DivideByKey, EqualityConstraint, guard_size_oblivious, has_free_symbols, ) print('DivideByKey.get(17)=', DivideByKey(4).get(17)) print('guard_size_oblivious(True)=', guard_size_oblivious(True)) print('has_free_symbols(3)=', has_free_symbols(3)) print('EqualityConstraint OK') print('npu:', torch.npu.is_available()) " 结果:  **(3)官方用例 pytest** bash cd /tmp python -m pytest --rootdir=/tmp /workspace/pytorch-upstream-210/test/test_dynamic_shapes.py -k has_free_symbols -xvs python -m pytest --rootdir=/tmp /workspace/pytorch-upstream-210/test/dynamo/test_misc.py -k guard_size_oblivious -xvs python -m pytest --rootdir=/tmp /workspace/pytorch-upstream-210/test/export/test_export.py -k test_unbacked_bindings_for_divisible_u_symint -xvs > torch.fx.experimental.symbolic_shapes.DivideByKey 相关 export 用例勿用 -k DivideByKey(会 0 selected),应使用 test_unbacked_bindings_for_divisible_u_symint。 **(4)patch 可应用性** bash cd /workspace/pytorch-upstream-210 git checkout -- test/dynamo/test_misc.py test/test_dynamic_shapes.py test/export/test_export.py git apply --check <path>/test_upstream/test/test_dynamic_shapes.py.patch && echo test_dynamic_shapes OK git apply --check <path>/test_upstream/test/dynamo/test_misc.py.patch && echo test_misc OK git apply --check <path>/test_upstream/test/export/test_export.py.patch && echo test_export OK 结果:  **UT 看护:** 已新增 test/test_symbolic_shapes.py;已为 3 个官方测试文件新增 test_upstream patch,纳入社区 test_upstream 机制。 --- # 【CheckList】 - [x] 代码注释完备,正确记录错误日志(测试代码含模块 Owner 注释;不涉及业务错误日志) - [x] 代码实现进行了返回值、空指针等校验(不涉及;仅为测试与 patch) - [x] PR标题正确使用类型标签(使用 test: 前缀) - [x] PR持续集成流水线(CI)执行通过,代码检查无异常 --- See merge request: Ascend/pytorch!36834 | 1 个月前 | |
test(futures): add test case patch for futures Co-authored-by: dinglaiping<1016581171@qq.com> # message auto-generated for no-merge-commit merge: !33279 merge add-testcasepatch-for-futures-2.10.0 into v2.10.0 test(futures): add test case patch for futures Created-by: dinglaiping Commit-by: dinglaiping Merged-by: ascend-robot Description: <!-- PR描述模板更新日期:20260203 --> # 【合入来源】 > <font color="red">**https://gitcode.com/Ascend/pytorch/issues/1670**</font>\ > <font color="red">**请勿携带内部流程信息(需求链接、问题单、内部issue等)**</font> [ ] 问题单 # 【修改方案】 > 请描述修改内容的具体实现,涉及哪些组件之间进行交互,可以用1、2、3、...进行罗列\ > 如果是需求或者重构类的PR,需要补充详细设计文档(说明上下游组件关系、时序图、类图、DFX能力等内容) 一、API功能 Future.value():该方法用于获取 Future 对象的结果值。当 Future 已经完成时,它会直接返回设置的结果;但如果 Future 是通过 set_exception 标记为完成的,调用 value() 会抛出对应的异常。这个 API 和 wait() 的区别在于它不会阻塞等待,只适用于已经完成的 Future。 Future.set_result(value):用于将 Future 标记为完成状态并设置结果值。一旦调用,Future 立即进入完成状态,所有等待该 Future 的线程都会被唤醒并收到这个结果。每个 Future 只能被标记完成一次,重复调用会触发 RuntimeError。 Future.set_exception(err):将 Future 标记为完成状态但携带一个异常。调用后 Future 被视为已完成,但任何尝试通过 wait() 或 value() 获取结果的调用都会抛出这个设置的异常。这在异步错误传播中非常有用。 Future.wait():阻塞当前线程直到 Future 完成,然后返回结果值。如果 Future 是通过 set_exception 完成的,wait() 会抛出设置的异常。这是最基础的获取 Future 结果的方式。 Future.done():返回一个布尔值指示 Future 是否已经完成。如果 Future 已经被 set_result 或 set_exception 标记过,返回 True;否则返回 False。可以用于非阻塞地检查状态。 Future.then(cb):注册一个回调函数,当 Future 完成时自动执行。回调函数接收完成的 Future 作为参数,可以调用 wait() 获取结果进行处理。then 返回一个新的 Future 对象,代表回调执行的结果,支持链式调用形成 Future 链条。如果回调本身抛出异常,新 Future 会携带这个异常。 Future.add_done_callback(cb):添加一个完成时的回调函数,与 then 不同,它不返回新的 Future,回调的错误会被静默忽略(仅记录日志)。多个回调按添加顺序执行,适合用于副作用操作(如状态标记、清理工作)。 torch.futures.collect_all(futs):接受一个 Future 列表,返回一个新的 Future,该 Future 在所有输入 Future 完成时完成,其结果是一个包含所有原始 Future 的列表,每个都可以通过 wait() 获取各自的结果。 torch.futures.wait_all(futs):接受一个 Future 列表,阻塞等待所有 Future 完成,直接返回一个包含所有结果的列表。如果任何一个 Future 携带异常,wait_all 会抛出 RuntimeError 包裹的异常信息。 二、测试用例完备性说明 PyTorch 社区原生测试用例(test_futures.py)对上述 9 个 API 实现全维度场景覆盖,核心验证内容如下: Future.set_exception 的验证:test_set_exception 测试用例创建了 Future 并调用 set_exception 设置 ValueError,然后验证 wait() 会抛出带有"Intentional"消息的 ValueError,同时也验证 value() 同样会抛出该异常。test_set_exception_multithreading 进一步在一个线程等待的同时,另一个线程设置异常,验证跨线程的错误传播。 多线程场景验证:test_set_exception_multithreading 使用 threading.Thread 在一个线程中调用 wait(),主线程中设置异常,验证异常能正确传播到等待线程。test_wait_multi_thread 则测试了在后台线程延迟设置结果,主线程调用 wait() 能正确阻塞并获取结果。 Future.done() 的验证:test_done 测试创建一个 Future,初始状态验证 done() 返回 False,调用 set_result 后验证 done() 返回 True。test_done_exception 则验证通过 then 链接触发异常的 Future,其 done() 状态也为 True,但 wait() 会抛出异常。 单次完成限制验证:test_mark_future_twice 专门测试多次调用 set_result 会触发 RuntimeError,提示"Future can only be marked completed once"。 序列化限制验证:test_pickle_future 验证 Future 对象不能被 pickle 序列化,尝试保存时会抛出 RuntimeError。 then 方法的验证:test_then 测试基本回调,验证回调能正确获取结果并返回新 Future。test_chained_then 创建了 20 个 then 链,每个回调给结果加 1,验证链式调用的计算顺序正确。test_then_error 系列包括三个子测试:test_then_wrong_arg 验证回调参数类型错误,test_then_no_arg 验证回调不接受参数的错误,test_then_raise 验证回调内部抛出异常的情况,都验证错误正确传播到新 Future。 add_done_callback 的验证:test_add_done_callback_simple 验证回调在 set_result 后被调用,并能正确获取结果。test_add_done_callback_maintains_callback_order 添加两个回调修改同一变量,验证执行顺序与添加顺序一致。test_add_done_callback_error_is_ignored 验证回调中的 ValueError 不会传播,只是被记录。test_add_done_callback_no_arg_error_is_ignored 验证参数不匹配的错误同样被忽略。 then 与 add_done_callback 交互验证:test_interleaving_then_and_add_done_callback_maintains_callback_order 交替添加 then 和 add_done_callback,验证回调执行顺序保持插入顺序。test_interleaving_then_and_add_done_callback_propagates_error 验证 then 的错误会传播到结果 Future,而 add_done_callback 的错误被忽略。 collect_all 的验证:test_collect_all 创建两个 Future,在一个后台线程中延迟设置第一个 Future 的结果,主线程立即设置第二个,然后验证 collect_all 返回的 Future 能正确收集两个结果,且等待时间由最慢的决定。 wait_all 的验证:test_wait_all(Windows 除外)先测试两个已完成的 Future,验证返回列表包含正确结果。然后测试包含异常的链条,验证 wait_all 会抛出 RuntimeError 包含"Expected error"消息。 空值处理验证:test_wait_none 验证向 torch.jit.wait、torch.futures.wait_all 和 torch.futures.collect_all 传递 None 时,都会抛出 RuntimeError 提示"Future can't be None"。 三、npu适配 3.1 api适配 torch.futures 模块 API 底层无硬件相关逻辑,所有异步结果管理、回调触发、异常传播等核心功能均为框架层通用实现,torch_npu 已完成 NPU 设备的底层适配,无需修改 API 源码,仅通过测试用例的设备相关调整即可实现 NPU 兼容。 3.2 测试用例适配 • 基础环境适配:新增 import torch_npu,让 PyTorch 框架识别 NPU 设备,支持 NPU 张量的创建与操作; • 张量设备调整:将原测试用例中默认的 CPU 张量(torch.ones(2,2))修改为 NPU 张量(torch.ones(2,2).npu()),确保异步计算的结果载体(张量)运行在 NPU 上,贴合 NPU 场景使用需求。 # 【资料变更】 > 不涉及 # 【接口变更】 > 不涉及 # 【功能验证】 > 说明测试场景,测试方法。如果本次测试方式与常规单元测试不同,请详细说明您的测试步骤\ > 新增/变更内容是否已新增/适配UT测试用例看护,并补充测试自验证截图 2.6版本 [root@hostname-fqv42 ~]# docker exec -it test26 bash root@hostname-fqv42:/home# python /root/torchnpuapi/test_futures_gai.py Fail to import hypothesis in common_utils, tests are not derandomized [E226 11:44:33.636064398 pybind_utils.h:209] Got the following error when running the callback: ValueError: Expected error At: /root/torchnpuapi/test_futures_gai.py(243): raise_value_error /usr/local/python/lib/python3.11/site-packages/torch/futures/__init__.py(245): set_result /root/torchnpuapi/test_futures_gai.py(236): _test_add_done_callback_error_ignored /root/torchnpuapi/test_futures_gai.py(245): test_add_done_callback_error_is_ignored /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(3108): wrapper /usr/local/python/lib/python3.11/unittest/case.py(579): _callTestMethod /usr/local/python/lib/python3.11/unittest/case.py(623): run /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(3215): _run_custom /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(3243): run /usr/local/python/lib/python3.11/unittest/case.py(678): __call__ /usr/local/python/lib/python3.11/unittest/suite.py(122): run /usr/local/python/lib/python3.11/unittest/suite.py(84): __call__ /usr/local/python/lib/python3.11/unittest/suite.py(122): run /usr/local/python/lib/python3.11/unittest/suite.py(84): __call__ /usr/local/python/lib/python3.11/unittest/runner.py(217): run /usr/local/python/lib/python3.11/unittest/main.py(274): runTests /usr/local/python/lib/python3.11/unittest/main.py(102): __init__ /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(1353): run_tests /root/torchnpuapi/test_futures_gai.py(347): <module> ..[E226 11:44:38.999984481 pybind_utils.h:209] Got the following error when running the callback: TypeError: TestFuture.test_add_done_callback_no_arg_error_is_ignored.<locals>.no_arg() takes 0 positional arguments but 1 was given .......[E226 11:44:38.132336345 pybind_utils.h:209] Got the following error when running the callback: ValueError: Expected error At: /root/torchnpuapi/test_futures_gai.py(287): raise_value_error /usr/local/python/lib/python3.11/site-packages/torch/futures/__init__.py(245): set_result /root/torchnpuapi/test_futures_gai.py(292): test_interleaving_then_and_add_done_callback_propagates_error /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(3108): wrapper /usr/local/python/lib/python3.11/unittest/case.py(579): _callTestMethod /usr/local/python/lib/python3.11/unittest/case.py(623): run /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(3215): _run_custom /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(3243): run /usr/local/python/lib/python3.11/unittest/case.py(678): __call__ /usr/local/python/lib/python3.11/unittest/suite.py(122): run /usr/local/python/lib/python3.11/unittest/suite.py(84): __call__ /usr/local/python/lib/python3.11/unittest/suite.py(122): run /usr/local/python/lib/python3.11/unittest/suite.py(84): __call__ /usr/local/python/lib/python3.11/unittest/runner.py(217): run /usr/local/python/lib/python3.11/unittest/main.py(274): runTests /usr/local/python/lib/python3.11/unittest/main.py(102): __init__ /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(1353): run_tests /root/torchnpuapi/test_futures_gai.py(347): <module> ..........[1, 2] ... ---------------------------------------------------------------------- Ran 22 tests in 6.038s OK root@hostname-fqv42:/home# ## 结果说明 执行test_futures.py测试用例后,终端输出包含若干[E226]级别的错误日志,但最终显示Ran 22 tests in 6.038s且OK,表明所有测试用例执行通过,日志中出现的报错属于测试用例设计的预期行为,非代码 Bug 或 NPU 适配问题。 # 【CheckList】 > PR提交人对以下CheckList自检项进行全量自检,自检通过或不涉及,均修改 [ ] 为 [x] - [x] 代码注释完备,正确记录错误日志 - [x] 代码实现进行了返回值、空指针等校验 - [x] PR标题正确使用类型标签,如:feat、fix、refactor、docs、test等 - [x] PR持续集成流水线(CI)执行通过,代码检查无异常 See merge request: Ascend/pytorch!33279 | 4 个月前 | |
test(futures): add test case patch for futures Co-authored-by: dinglaiping<1016581171@qq.com> # message auto-generated for no-merge-commit merge: !33279 merge add-testcasepatch-for-futures-2.10.0 into v2.10.0 test(futures): add test case patch for futures Created-by: dinglaiping Commit-by: dinglaiping Merged-by: ascend-robot Description: <!-- PR描述模板更新日期:20260203 --> # 【合入来源】 > <font color="red">**https://gitcode.com/Ascend/pytorch/issues/1670**</font>\ > <font color="red">**请勿携带内部流程信息(需求链接、问题单、内部issue等)**</font> [ ] 问题单 # 【修改方案】 > 请描述修改内容的具体实现,涉及哪些组件之间进行交互,可以用1、2、3、...进行罗列\ > 如果是需求或者重构类的PR,需要补充详细设计文档(说明上下游组件关系、时序图、类图、DFX能力等内容) 一、API功能 Future.value():该方法用于获取 Future 对象的结果值。当 Future 已经完成时,它会直接返回设置的结果;但如果 Future 是通过 set_exception 标记为完成的,调用 value() 会抛出对应的异常。这个 API 和 wait() 的区别在于它不会阻塞等待,只适用于已经完成的 Future。 Future.set_result(value):用于将 Future 标记为完成状态并设置结果值。一旦调用,Future 立即进入完成状态,所有等待该 Future 的线程都会被唤醒并收到这个结果。每个 Future 只能被标记完成一次,重复调用会触发 RuntimeError。 Future.set_exception(err):将 Future 标记为完成状态但携带一个异常。调用后 Future 被视为已完成,但任何尝试通过 wait() 或 value() 获取结果的调用都会抛出这个设置的异常。这在异步错误传播中非常有用。 Future.wait():阻塞当前线程直到 Future 完成,然后返回结果值。如果 Future 是通过 set_exception 完成的,wait() 会抛出设置的异常。这是最基础的获取 Future 结果的方式。 Future.done():返回一个布尔值指示 Future 是否已经完成。如果 Future 已经被 set_result 或 set_exception 标记过,返回 True;否则返回 False。可以用于非阻塞地检查状态。 Future.then(cb):注册一个回调函数,当 Future 完成时自动执行。回调函数接收完成的 Future 作为参数,可以调用 wait() 获取结果进行处理。then 返回一个新的 Future 对象,代表回调执行的结果,支持链式调用形成 Future 链条。如果回调本身抛出异常,新 Future 会携带这个异常。 Future.add_done_callback(cb):添加一个完成时的回调函数,与 then 不同,它不返回新的 Future,回调的错误会被静默忽略(仅记录日志)。多个回调按添加顺序执行,适合用于副作用操作(如状态标记、清理工作)。 torch.futures.collect_all(futs):接受一个 Future 列表,返回一个新的 Future,该 Future 在所有输入 Future 完成时完成,其结果是一个包含所有原始 Future 的列表,每个都可以通过 wait() 获取各自的结果。 torch.futures.wait_all(futs):接受一个 Future 列表,阻塞等待所有 Future 完成,直接返回一个包含所有结果的列表。如果任何一个 Future 携带异常,wait_all 会抛出 RuntimeError 包裹的异常信息。 二、测试用例完备性说明 PyTorch 社区原生测试用例(test_futures.py)对上述 9 个 API 实现全维度场景覆盖,核心验证内容如下: Future.set_exception 的验证:test_set_exception 测试用例创建了 Future 并调用 set_exception 设置 ValueError,然后验证 wait() 会抛出带有"Intentional"消息的 ValueError,同时也验证 value() 同样会抛出该异常。test_set_exception_multithreading 进一步在一个线程等待的同时,另一个线程设置异常,验证跨线程的错误传播。 多线程场景验证:test_set_exception_multithreading 使用 threading.Thread 在一个线程中调用 wait(),主线程中设置异常,验证异常能正确传播到等待线程。test_wait_multi_thread 则测试了在后台线程延迟设置结果,主线程调用 wait() 能正确阻塞并获取结果。 Future.done() 的验证:test_done 测试创建一个 Future,初始状态验证 done() 返回 False,调用 set_result 后验证 done() 返回 True。test_done_exception 则验证通过 then 链接触发异常的 Future,其 done() 状态也为 True,但 wait() 会抛出异常。 单次完成限制验证:test_mark_future_twice 专门测试多次调用 set_result 会触发 RuntimeError,提示"Future can only be marked completed once"。 序列化限制验证:test_pickle_future 验证 Future 对象不能被 pickle 序列化,尝试保存时会抛出 RuntimeError。 then 方法的验证:test_then 测试基本回调,验证回调能正确获取结果并返回新 Future。test_chained_then 创建了 20 个 then 链,每个回调给结果加 1,验证链式调用的计算顺序正确。test_then_error 系列包括三个子测试:test_then_wrong_arg 验证回调参数类型错误,test_then_no_arg 验证回调不接受参数的错误,test_then_raise 验证回调内部抛出异常的情况,都验证错误正确传播到新 Future。 add_done_callback 的验证:test_add_done_callback_simple 验证回调在 set_result 后被调用,并能正确获取结果。test_add_done_callback_maintains_callback_order 添加两个回调修改同一变量,验证执行顺序与添加顺序一致。test_add_done_callback_error_is_ignored 验证回调中的 ValueError 不会传播,只是被记录。test_add_done_callback_no_arg_error_is_ignored 验证参数不匹配的错误同样被忽略。 then 与 add_done_callback 交互验证:test_interleaving_then_and_add_done_callback_maintains_callback_order 交替添加 then 和 add_done_callback,验证回调执行顺序保持插入顺序。test_interleaving_then_and_add_done_callback_propagates_error 验证 then 的错误会传播到结果 Future,而 add_done_callback 的错误被忽略。 collect_all 的验证:test_collect_all 创建两个 Future,在一个后台线程中延迟设置第一个 Future 的结果,主线程立即设置第二个,然后验证 collect_all 返回的 Future 能正确收集两个结果,且等待时间由最慢的决定。 wait_all 的验证:test_wait_all(Windows 除外)先测试两个已完成的 Future,验证返回列表包含正确结果。然后测试包含异常的链条,验证 wait_all 会抛出 RuntimeError 包含"Expected error"消息。 空值处理验证:test_wait_none 验证向 torch.jit.wait、torch.futures.wait_all 和 torch.futures.collect_all 传递 None 时,都会抛出 RuntimeError 提示"Future can't be None"。 三、npu适配 3.1 api适配 torch.futures 模块 API 底层无硬件相关逻辑,所有异步结果管理、回调触发、异常传播等核心功能均为框架层通用实现,torch_npu 已完成 NPU 设备的底层适配,无需修改 API 源码,仅通过测试用例的设备相关调整即可实现 NPU 兼容。 3.2 测试用例适配 • 基础环境适配:新增 import torch_npu,让 PyTorch 框架识别 NPU 设备,支持 NPU 张量的创建与操作; • 张量设备调整:将原测试用例中默认的 CPU 张量(torch.ones(2,2))修改为 NPU 张量(torch.ones(2,2).npu()),确保异步计算的结果载体(张量)运行在 NPU 上,贴合 NPU 场景使用需求。 # 【资料变更】 > 不涉及 # 【接口变更】 > 不涉及 # 【功能验证】 > 说明测试场景,测试方法。如果本次测试方式与常规单元测试不同,请详细说明您的测试步骤\ > 新增/变更内容是否已新增/适配UT测试用例看护,并补充测试自验证截图 2.6版本 [root@hostname-fqv42 ~]# docker exec -it test26 bash root@hostname-fqv42:/home# python /root/torchnpuapi/test_futures_gai.py Fail to import hypothesis in common_utils, tests are not derandomized [E226 11:44:33.636064398 pybind_utils.h:209] Got the following error when running the callback: ValueError: Expected error At: /root/torchnpuapi/test_futures_gai.py(243): raise_value_error /usr/local/python/lib/python3.11/site-packages/torch/futures/__init__.py(245): set_result /root/torchnpuapi/test_futures_gai.py(236): _test_add_done_callback_error_ignored /root/torchnpuapi/test_futures_gai.py(245): test_add_done_callback_error_is_ignored /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(3108): wrapper /usr/local/python/lib/python3.11/unittest/case.py(579): _callTestMethod /usr/local/python/lib/python3.11/unittest/case.py(623): run /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(3215): _run_custom /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(3243): run /usr/local/python/lib/python3.11/unittest/case.py(678): __call__ /usr/local/python/lib/python3.11/unittest/suite.py(122): run /usr/local/python/lib/python3.11/unittest/suite.py(84): __call__ /usr/local/python/lib/python3.11/unittest/suite.py(122): run /usr/local/python/lib/python3.11/unittest/suite.py(84): __call__ /usr/local/python/lib/python3.11/unittest/runner.py(217): run /usr/local/python/lib/python3.11/unittest/main.py(274): runTests /usr/local/python/lib/python3.11/unittest/main.py(102): __init__ /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(1353): run_tests /root/torchnpuapi/test_futures_gai.py(347): <module> ..[E226 11:44:38.999984481 pybind_utils.h:209] Got the following error when running the callback: TypeError: TestFuture.test_add_done_callback_no_arg_error_is_ignored.<locals>.no_arg() takes 0 positional arguments but 1 was given .......[E226 11:44:38.132336345 pybind_utils.h:209] Got the following error when running the callback: ValueError: Expected error At: /root/torchnpuapi/test_futures_gai.py(287): raise_value_error /usr/local/python/lib/python3.11/site-packages/torch/futures/__init__.py(245): set_result /root/torchnpuapi/test_futures_gai.py(292): test_interleaving_then_and_add_done_callback_propagates_error /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(3108): wrapper /usr/local/python/lib/python3.11/unittest/case.py(579): _callTestMethod /usr/local/python/lib/python3.11/unittest/case.py(623): run /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(3215): _run_custom /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(3243): run /usr/local/python/lib/python3.11/unittest/case.py(678): __call__ /usr/local/python/lib/python3.11/unittest/suite.py(122): run /usr/local/python/lib/python3.11/unittest/suite.py(84): __call__ /usr/local/python/lib/python3.11/unittest/suite.py(122): run /usr/local/python/lib/python3.11/unittest/suite.py(84): __call__ /usr/local/python/lib/python3.11/unittest/runner.py(217): run /usr/local/python/lib/python3.11/unittest/main.py(274): runTests /usr/local/python/lib/python3.11/unittest/main.py(102): __init__ /usr/local/python/lib/python3.11/site-packages/torch/testing/_internal/common_utils.py(1353): run_tests /root/torchnpuapi/test_futures_gai.py(347): <module> ..........[1, 2] ... ---------------------------------------------------------------------- Ran 22 tests in 6.038s OK root@hostname-fqv42:/home# ## 结果说明 执行test_futures.py测试用例后,终端输出包含若干[E226]级别的错误日志,但最终显示Ran 22 tests in 6.038s且OK,表明所有测试用例执行通过,日志中出现的报错属于测试用例设计的预期行为,非代码 Bug 或 NPU 适配问题。 # 【CheckList】 > PR提交人对以下CheckList自检项进行全量自检,自检通过或不涉及,均修改 [ ] 为 [x] - [x] 代码注释完备,正确记录错误日志 - [x] 代码实现进行了返回值、空指针等校验 - [x] PR标题正确使用类型标签,如:feat、fix、refactor、docs、test等 - [x] PR持续集成流水线(CI)执行通过,代码检查无异常 See merge request: Ascend/pytorch!33279 | 4 个月前 |
Patch 批量应用脚本使用说明
目录结构
- 核心仓库地址
- 官方 PyTorch 仓库(v2.10.0 版本):https://github.com/pytorch/pytorch/tree/v2.10.0,需拉取该仓库并切换至 tags/v2.10.0 标签。
- 补丁仓库(Ascend/pytorch):https://gitcode.com/Ascend/pytorch,仅需提取该仓库中的 patch 目录。
- 核心目录结构
pytorch/ # PyTorch 源码根目录
├─ ...(其他 PyTorch 原生文件/目录)
└─ test_upstream/ # 补丁目录
├─ apply_patches.sh # 批量应用脚本
├─ *.patch # 补丁文件(支持子目录嵌套)
├─ ...(其他补丁子目录)
环境要求
仅需安装git即可
使用方法
-
将本仓库的test_upstream文件夹整体复制到本地的PyTorch官方仓库中
-
运行脚本文件
cd test_upstream
./apply_patches.sh
脚本执行说明:自动定位 PyTorch 根目录,递归扫描所有 .patch文件,按文件名排序强制应用,冲突部分生成 .rej 文件.
注意事项
- 所有补丁仅适配 PyTorch tags/v2.10.0,其他版本可能导致应用失败,务必提前校验版本。
- test_upstream 目录需整体复制至 PyTorch 根目录。
- 生成 .rej 冲突文件时,需手动解决冲突后重新执行脚本。