已合并
test(futures): add test case patch for futures #33279
dinglaiping创建于 4月8日
test(futures): add test case patch for futures #33279
已合并
dinglaiping创建于 4月8日
已删除 :add-testcasepatch-for-futures-2.10.0合入到Ascend/pytorchv2.10.0
3 个文件变更+239-0
Atest_upstream/apply_patch.sh+66-0
@@ -0,0 +1,66 @@
1+#!/bin/bash
2+ 
3+# ====================== 【重要】配置项 ======================
4+# 源码根目录相对于patch目录的路径 对于我们的项目来说是根目录相对于test_upstream的路径,也就是..
5+RELATIVE_TO_ROOT=..
6+# ==========================================================
7+ 
8+# 自动获取当前脚本所在目录
9+SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
10+# 自动计算源码根目录
11+ROOT_DIR=$(cd "$SCRIPT_DIR/$RELATIVE_TO_ROOT" &>/dev/null && pwd)
12+PATCH_DIR="$SCRIPT_DIR"
13+ 
14+# 检查根目录是否合法
15+if [ ! -d "$ROOT_DIR" ]; then
16+ echo "错误:无法定位源码根目录!"
17+ echo "请检查 RELATIVE_TO_ROOT 配置"
18+ exit 1
19+fi
20+ 
21+echo "================================================"
22+echo " 自动批量应用 patch"
23+echo "================================================"
24+echo "源码根目录:$ROOT_DIR"
25+echo "Patch 目录:$PATCH_DIR"
26+echo "================================================"
27+ 
28+# 进入源码根目录
29+cd "$ROOT_DIR" || exit 1
30+ 
31+# 递归查找所有 patch 文件并排序
32+PATCH_FILES=$(find "$PATCH_DIR" -type f \( -name "*.patch" -o -name "*.diff" \) | sort)
33+ 
34+if [ -z "$PATCH_FILES" ]; then
35+ echo "未找到任何 .patch / .diff 文件"
36+ exit 0
37+fi
38+ 
39+count=0
40+success=0
41+fail=0
42+ 
43+# 逐个应用
44+for patch in $PATCH_FILES; do
45+ count=$((count+1))
46+ echo -e "\n[$count] 应用:$patch"
47+ 
48+ patch -p1 --no-backup-if-mismatch -f < "$patch"
49+ 
50+ if [ $? -eq 0 ]; then
51+ echo "成功"
52+ success=$((success+1))
53+ else
54+ echo "失败!停止执行"
55+ fail=$((fail+1))
56+ exit 1
57+ fi
58+done
59+ 
60+echo -e "\n================================================"
61+echo " 全部完成"
62+echo "================================================"
63+echo "总计:$count 个"
64+echo "成功:$success 个"
65+echo "失败:$fail 个"
66+echo "================================================"
Atest_upstream/readme.md+42-0
@@ -0,0 +1,42 @@
1+# Patch 批量应用脚本使用说明
2+ 
3+## 目录结构
4+ 
5+1. 核心仓库地址
6+ 
7+- 官方 PyTorch 仓库(v2.10.0 版本):https://github.com/pytorch/pytorch/tree/v2.10.0,需拉取该仓库并切换至 tags/v2.10.0 标签。
8+- 补丁仓库(Ascend/pytorch):https://gitcode.com/Ascend/pytorch,仅需提取该仓库中的 patch 目录。
9+ 
10+2. 核心目录结构
11+ 
12+```coldFusion
13+ pytorch/ # PyTorch 源码根目录
14+ ├─ ...(其他 PyTorch 原生文件/目录)
15+ └─ test_upstream/ # 补丁目录
16+ ├─ apply_patches.sh # 批量应用脚本
17+ ├─ *.patch # 补丁文件(支持子目录嵌套)
18+ ├─ ...(其他补丁子目录)
19+```
20+ 
21+## 环境要求
22+ 
23+仅需安装git即可
24+ 
25+## 使用方法
26+ 
27+1. 将本仓库的test_upstream文件夹整体复制到本地的PyTorch官方仓库中
28+ 
29+2. 运行脚本文件
30+ 
31+```bash
32+cd test_upstream
33+./apply_patches.sh
34+```
35+ 
36+脚本执行说明:自动定位 PyTorch 根目录,递归扫描所有 .patch文件,按文件名排序强制应用,冲突部分生成 .rej 文件.
37+ 
38+## 注意事项
39+ 
40+- 所有补丁仅适配 PyTorch tags/v2.10.0,其他版本可能导致应用失败,务必提前校验版本。
41+- test_upstream 目录需整体复制至 PyTorch 根目录。
42+- 生成 .rej 冲突文件时,需手动解决冲突后重新执行脚本。
Atest_upstream/test/test_futures.py.patch+131-0
@@ -0,0 +1,131 @@
1+diff --git a/test/test_futures.py b/test/test_futures.py
2+index dd1e79f..caf52f9 100644
3+--- a/test/test_futures.py
4++++ b/test/test_futures.py
5+@@ -8,6 +8,7 @@ import unittest
6+ from torch.futures import Future
7+ from torch.testing._internal.common_utils import IS_WINDOWS, TestCase, TemporaryFileName, run_tests
8+ from typing import TypeVar
9++import torch_npu
10+
11+ T = TypeVar("T")
12+
13+@@ -79,7 +80,7 @@ class TestFuture(TestCase):
14+ f = Future[torch.Tensor]()
15+ self.assertFalse(f.done())
16+
17+- f.set_result(torch.ones(2, 2))
18++ f.set_result(torch.ones(2, 2).npu())
19+ self.assertTrue(f.done())
20+
21+ def test_done_exception(self) -> None:
22+@@ -90,7 +91,7 @@ class TestFuture(TestCase):
23+
24+ f1 = Future[torch.Tensor]()
25+ self.assertFalse(f1.done())
26+- f1.set_result(torch.ones(2, 2))
27++ f1.set_result(torch.ones(2, 2).npu())
28+ self.assertTrue(f1.done())
29+
30+ f2 = f1.then(raise_exception)
31+@@ -100,9 +101,9 @@ class TestFuture(TestCase):
32+
33+ def test_wait(self) -> None:
34+ f = Future[torch.Tensor]()
35+- f.set_result(torch.ones(2, 2))
36++ f.set_result(torch.ones(2, 2).npu())
37+
38+- self.assertEqual(f.wait(), torch.ones(2, 2))
39++ self.assertEqual(f.wait(), torch.ones(2, 2).npu())
40+
41+ def test_wait_multi_thread(self) -> None:
42+
43+@@ -112,10 +113,10 @@ class TestFuture(TestCase):
44+
45+ f = Future[torch.Tensor]()
46+
47+- t = threading.Thread(target=slow_set_future, args=(f, torch.ones(2, 2)))
48++ t = threading.Thread(target=slow_set_future, args=(f, torch.ones(2, 2).npu()))
49+ t.start()
50+
51+- self.assertEqual(f.wait(), torch.ones(2, 2))
52++ self.assertEqual(f.wait(), torch.ones(2, 2).npu())
53+ t.join()
54+
55+ def test_mark_future_twice(self) -> None:
56+@@ -138,9 +139,9 @@ class TestFuture(TestCase):
57+ fut = Future[torch.Tensor]()
58+ then_fut = fut.then(lambda x: x.wait() + 1)
59+
60+- fut.set_result(torch.ones(2, 2))
61+- self.assertEqual(fut.wait(), torch.ones(2, 2))
62+- self.assertEqual(then_fut.wait(), torch.ones(2, 2) + 1)
63++ fut.set_result(torch.ones(2, 2).npu())
64++ self.assertEqual(fut.wait(), torch.ones(2, 2).npu())
65++ self.assertEqual(then_fut.wait(), torch.ones(2, 2).npu() + 1)
66+
67+ def test_chained_then(self):
68+ fut = Future[torch.Tensor]()
69+@@ -150,10 +151,10 @@ class TestFuture(TestCase):
70+ last_fut = last_fut.then(add_one)
71+ futs.append(last_fut)
72+
73+- fut.set_result(torch.ones(2, 2))
74++ fut.set_result(torch.ones(2, 2).npu())
75+
76+ for i in range(len(futs)):
77+- self.assertEqual(futs[i].wait(), torch.ones(2, 2) + i + 1)
78++ self.assertEqual(futs[i].wait(), torch.ones(2, 2).npu() + i + 1)
79+
80+ def _test_then_error(self, cb, errMsg):
81+ fut = Future[int]()
82+@@ -197,8 +198,8 @@ class TestFuture(TestCase):
83+ fut.add_done_callback(callback)
84+
85+ self.assertFalse(callback_result)
86+- fut.set_result(torch.ones(2, 2))
87+- self.assertEqual(fut.wait(), torch.ones(2, 2))
88++ fut.set_result(torch.ones(2, 2).npu())
89++ self.assertEqual(fut.wait(), torch.ones(2, 2).npu())
90+ self.assertTrue(callback_result)
91+
92+ def test_add_done_callback_maintains_callback_order(self):
93+@@ -218,8 +219,8 @@ class TestFuture(TestCase):
94+ fut.add_done_callback(callback_set1)
95+ fut.add_done_callback(callback_set2)
96+
97+- fut.set_result(torch.ones(2, 2))
98+- self.assertEqual(fut.wait(), torch.ones(2, 2))
99++ fut.set_result(torch.ones(2, 2).npu())
100++ self.assertEqual(fut.wait(), torch.ones(2, 2).npu())
101+ # set2 called last, callback_result = 2
102+ self.assertEqual(callback_result, 2)
103+
104+@@ -269,10 +270,10 @@ class TestFuture(TestCase):
105+ then_fut = fut.then(callback_then)
106+ fut.add_done_callback(callback_set2)
107+
108+- fut.set_result(torch.ones(2, 2))
109+- self.assertEqual(fut.wait(), torch.ones(2, 2))
110++ fut.set_result(torch.ones(2, 2).npu())
111++ self.assertEqual(fut.wait(), torch.ones(2, 2).npu())
112+ # then_fut's callback is called with callback_result = 1
113+- self.assertEqual(then_fut.wait(), torch.ones(2, 2) + 1)
114++ self.assertEqual(then_fut.wait(), torch.ones(2, 2).npu() + 1)
115+ # set2 called last, callback_result = 2
116+ self.assertEqual(callback_result, 2)
117+
118+@@ -283,11 +284,11 @@ class TestFuture(TestCase):
119+ fut = Future[torch.Tensor]()
120+ then_fut = fut.then(raise_value_error)
121+ fut.add_done_callback(raise_value_error)
122+- fut.set_result(torch.ones(2, 2))
123++ fut.set_result(torch.ones(2, 2).npu())
124+
125+ # error from add_done_callback's callback is swallowed
126+ # error from then's callback is not
127+- self.assertEqual(fut.wait(), torch.ones(2, 2))
128++ self.assertEqual(fut.wait(), torch.ones(2, 2).npu())
129+ with self.assertRaisesRegex(RuntimeError, "Expected error"):
130+ then_fut.wait()
131+