已合并
test: adapt Tensor.indices upstream case for NPU #42541
test: adapt Tensor.indices upstream case for NPU #42541
已合并
Flipped创建于 7月23日
Flipped
Flipped
7月23日

【合入来源】

issue: [社区任务]: Tensor.indices API一致性验证补齐 #3317
issue: 【社区任务】7月社区任务第一期-Ascend for PyTorch API 一致性开发(83) #2706

【修改方案】

1. API基础功能及用例覆盖

Tensor.indices 用于获取已合并 Sparse COO Tensor 的索引张量:

  • 已合并 Tensor 调用后,返回结果应与 Tensor._indices 一致;
  • 未合并 Tensor 调用时,应抛出异常。

PyTorch v2.7.1 官方用例位置:

test/test_sparse.py::TestSparse.test_basic
test/test_sparse.py:L289-L322

该用例直接覆盖:

  • 未合并 Sparse COO Tensor 的异常场景;
  • 已合并 Sparse COO Tensor 的索引返回结果;
  • Tensor.indices 与 Tensor._indices 的一致性。

因此,本次无需新增自定义测试用例,只需适配现有官方用例。

2. v2.7.1原有patch情况

v2.7.1 已存在:

test_upstream/test/test_sparse.py.patch

原 patch 存在以下问题:

  1. 未适配 TestSparse.test_basic 的 NPU 数据类型。官方用例使用 torch.double 和 torch.cdouble,在 NPU 上执行 coalesce() 时对应的 float64 和 complex128 不受支持,导致测试尚未执行到 Tensor.indices 断言即失败。
  2. 原 patch 中两处代码已经将测试设备由 cuda:0 修改为 npu:0,但外层仍使用 torch.cuda.is_available() 判断,设备可用性判断与实际测试设备不一致。

3. 本次修改内容

为 TestSparse.test_basic 增加 PrivateUse1 专用数据类型:

@coalescedonoff
@dtypes(torch.double, torch.cdouble)
@dtypesIfPRIVATEUSE1(torch.float)
def test_basic(self, device, dtype, coalesced):

修改后:

  • CPU 继续使用 torch.double 和 torch.cdouble;
  • NPU 使用支持的 torch.float;
  • 保留官方用例原有验证逻辑;
  • 不修改 Tensor.indices 接口实现。

同时将两处 NPU 测试路径的条件守卫修改为:

if torch.npu.is_available():

确保条件守卫与内部使用的 npu:0 设备保持一致。

本次先在干净的 PyTorch v2.7.1 工作树中应用原有 patch,再修改对应源码,最终通过 git diff -- test/test_sparse.py 重新生成完整 patch,未手工编辑 patch 文件。

【资料变更】

不涉及资料修改。

已基于 torch-npu 最新 master 分支检查资料目录:

docs/zh/api/native_api

PyTorch 2.7.1、2.9.0、2.10.0、2.11.0 和 2.12.0 对应的 torch-Tensor.md 中均已存在唯一的 Tensor.indices 条目,支持状态均登记为:

是否支持:是,暂不支持 Ascend 950DT

Tensor.indices 属于非计算类 API,与数据类型无关。现有资料未填写 fp16、fp32 等具体数据类型,符合当前资料填写要求。

【接口变更】

不涉及。

本次仅适配 PyTorch 官方测试用例,不修改客户可见接口及其功能实现。

【功能验证】

运行环境

操作系统:Ubuntu 22.04.5 LTS
机器架构:aarch64
昇腾硬件:Ascend 910B3 NPU
npu-smi版本:25.2.0
CANN版本:9.1.0-beta.1
Python版本:3.11
torch版本:2.7.1+cpu
torch-npu版本:2.7.1

将最终 patch 应用到干净的 PyTorch v2.7.1 工作树后,运行官方目标用例。

cd /workspace

CHECK_DIR="/workspace/pytorch-v2.7.1-patch-check"
PATCH="/workspace/torch-npu-v2.7.1/test_upstream/test/test_sparse.py.patch"

git -C /workspace/pytorch-v2.7.1 worktree remove \
    "${CHECK_DIR}" --force 2>/dev/null || true
rm -rf "${CHECK_DIR}"
git -C /workspace/pytorch-v2.7.1 worktree prune
git -C /workspace/pytorch-v2.7.1 worktree add \
    --detach "${CHECK_DIR}" HEAD

git -C "${CHECK_DIR}" apply --check "${PATCH}"
git -C "${CHECK_DIR}" apply "${PATCH}"
git -C "${CHECK_DIR}" diff --check

source /workspace/envs/torch-npu-2.7.1/bin/activate
source /usr/local/Ascend/ascend-toolkit/set_env.sh

unset PYTHONPATH
export PYTHONPATH="${CHECK_DIR}/test"
export PYTHONNOUSERSITE=1
export PYTORCH_PRINT_REPRO_ON_FAILURE=0

python - <<'PY'
import runpy
import sys

import torch
import torch_npu


torch.npu.get_device_capability = lambda *args, **kwargs: (0, 0)

test_file = (
    "/workspace/pytorch-v2.7.1-patch-check/"
    "test/test_sparse.py"
)

sys.argv = [
    test_file,
    "TestSparsePRIVATEUSE1.test_basic_npu_float32",
    "-v",
]

runpy.run_path(test_file, run_name="__main__")
PY

验证结果:

test_basic_npu_float32 (__main__.TestSparsePRIVATEUSE1.test_basic_npu_float32) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.611s

OK

最终 patch 可以在干净工作树中正常应用,修改后的官方用例已在 NPU 上通过,可以覆盖 Tensor.indices 的核心功能。

【CheckList】

likedislike
Pull Request已成功合入, 合并人@ascend-robot
(感谢 Flipped 的贡献)
FlippedFlipped
7月23日 创建了 pull request,commit c6931d43
atomgit-bot
atomgit-bot
7月23日 评论:

变更摘要

本次变更对 test_upstream/test/test_sparse.py.patch 进行增强,针对 NPU(PrivateUse1)设备适配 Tensor.indices 相关的上游测试用例。由于 NPU 不支持 float64 和 complex128 数据类型,原有 test_basic 用例在 coalesce() 阶段即失败,导致 Tensor.indices 断言未被覆盖。本次通过引入 dtypesIfPRIVATEUSE1 装饰器为 NPU 指定 torch.float 替代类型,并将多个仅限 CUDA 的测试方法扩展为同时支持 NPU,确保稀疏 COO Tensor 的 indices 行为在 NPU 上得到完整验证。

主要改动

  • 引入 dtypesIfPRIVATEUSE1 装饰器:在 test_sparse.py.patch 的导入语句中新增 dtypesIfPRIVATEUSE1,为 NPU 设备提供专用数据类型条件装饰能力。

  • 为 test_basic 添加 NPU 数据类型适配:在 TestSparse.test_basic 方法上添加 @dtypesIfPRIVATEUSE1(torch.float),使 NPU 使用 torch.float 替代不支持的 torch.double 和 torch.cdouble,确保 coalesce() 可正常执行并覆盖 Tensor.indices 断言。

  • 扩展多个测试方法至 NPU 设备:将 test_cuda_empty、test_storage_not_null、test_same_gpu、test_factory_device_type_inference 等方法的 @onlyCUDA 替换为 @onlyCUDAAndPRIVATEUSE1,使这些稀疏张量测试同步覆盖 NPU。

  • 适配 test_factory_diags 和 test_empty_full 的设备类型逻辑:在这两个测试方法中添加 NPU 设备可用性判断分支,使稀疏张量工厂方法的 dtype 测试覆盖 NPU 场景。

likedislike
不准确?
atomgit-bot
atomgit-bot
7月23日 评论:

代码审查

审查总结

本次审查针对文件 test_upstream/test/test_sparse.py.patch 的变更,共发现 2 个 P1 问题:

优先级 数量 说明
P1 2 torch.cuda.is_available() 守卫下使用了 npu:0 设备,条件与设备不一致
P0 0 —
P2 0 —
P3 0 —

总体风险判断:中等风险。新增的两个 patch hunk 存在逻辑错误:将设备从 cuda:0 改为 npu:0,但外层条件守卫仍为 if torch.cuda.is_available():。这会导致在仅有 NPU 无 CUDA 的环境中测试被跳过,而在 CUDA 可用但 NPU 不可用时抛出 RuntimeError。建议将两处条件均改为 if torch.npu.is_available():。

已审查文件清单:

  • test_upstream/test/test_sparse.py.patch — 发现 2 个 P1 问题(如上所述)
类型 数量
🔴 阻塞 2
🟡 建议 0

⛔ 需要修改

likedislike
不准确?
ascend-robotascend-robot成员
7月23日 添加了label:ascend-cla/yes
此处折叠了57条消息 查看更多
ascend-robotascend-robot成员
8月5日 添加了label:lgtm
ascend-robotascend-robot成员
8月5日 删除了label:ci-pipeline-passed
ascend-robotascend-robot成员
8月5日 解决了最后一个问题
ascend-robotascend-robot成员
8月5日 合入了pull request
ascend-robot
ascend-robot成员
8月5日 评论:
流水线 pytorch_gitcode_PR_multiVersion#13685 [ commitID:d456af13 ] 已完成
likedislike