CANN PyPTO 算子开发指南:pypto.index_select 张量索引算子详解

发布时间:2026/9/20 23:57:23

CANN PyPTO 算子开发指南:pypto.index_select 张量索引算子详解 CANN PyPTO 算子开发指南pypto.index_select 张量索引算子详解【免费下载链接】pyptoPyPTO发音: pai p-t-oParallel Tensor/Tile Operation编程范式。项目地址: https://gitcode.com/cann/pyptopypto.index_select是 CANN PyPTOParallel Tensor/Tile Operation 编程范式提供的张量索引算子它沿指定维度dim依据索引张量index中的元素从输入张量input中挑选数据并重组为一个新张量常用于 embedding 查表、序列重排、数据采样等需要按索引收集数据的场景。本文以 pypto-index_select 接口文档 为主体结合仓库内 Python 前端封装、pybind11 绑定与 C 算子实现源码完整讲解该接口的功能语义、参数约束、TileShape 切分配置与调用示例帮助开发者在 Ascend 硬件上正确、高效地完成按索引取数。产品支持情况该接口在当前仓库所适配的昇腾平台上均有支持各产品线覆盖情况如下产品系列支持情况Ascend 950PR / Ascend 950DT支持Atlas A3 训练系列产品 / Atlas A3 推理系列产品支持Atlas A2 训练系列产品 / Atlas A2 推理系列产品支持不同型号所支持的输入数据类型有所差异具体以 约束说明 中的数据类型列表为准。功能说明pypto.index_select返回一个新的张量该张量使用索引index中的元素沿维度dim对输入张量进行索引。其行为可理解为把input沿dim轴展开成一串切片再用index里的下标去挑选这些切片并按顺序拼接。返回张量与原始输入张量具有相同的维度数其中第dim维度的大小与索引index的长度相同其余维度的大小与原始张量保持一致。形式化定义如下设输入input形状为 $(S_0, S_1, \ldots, S_{n-1})$dim d索引index形状为 $(I_0,)$$$ \begin{array}{l} \text{shape}(\mathbf{input}) (S_0, S_1, \ldots, S_{n-1}) \ dim d \ \text{shape}(\mathbf{index}) (I_0,) \ \text{shape}(\mathbf{result}) (S_0, \ldots, S_{d-1}, I_0, S_{d1}, \ldots, S_{n-1}) \ \mathbf{result}[s_0, \ldots, s_{d-1}, i, s_{d1}, \ldots, s_{n-1}] \mathbf{input}[s_0, \ldots, s_{d-1}, \mathbf{index}[i], s_{d1}, \ldots, s_{n-1}] \end{array} $$从结果形状可以看出dim轴被替换为索引的长度其余轴原样保留。仓库中 C 层的形状推导逻辑 gather.cpp 正是按此规则实现// result shape: params.shape[:aixs] indices.shape params.shape[axis1:] std::vectorint64_t resultShape params-shape; resultShape.erase(resultShape.begin() axis); resultShape.insert(resultShape.begin() axis, indices-shape.begin(), indices-shape.end());注意index本身支持 1~2 维因此上述公式可推广为结果第dim轴及紧随其后的若干轴被替换为index的完整形状详见下文返回值说明。函数原型index_select(input: Tensor, dim: int, index: Tensor) - Tensor参数说明参数名输入/输出说明input输入源操作数类型为 Tensor。不同型号支持的数据类型有所差异详见约束说明。不支持空 TensorShape 仅支持 1~4 维Shape Size 不大于 2147483647即 INT32_MAX。dim输入int 类型索引的维度支持任意不超过 input 维数的值取值范围-input.dim dim input.dim支持负数负值解释为dim input.dim详见约束说明。index输入索引操作数类型为 Tensor。支持的数据类型为 DT_INT32、DT_INT64不支持空 TensorShape 只支持 1~2 维Shape Size 不大于 2147483647即 INT32_MAX且元素必须为合法索引即不超过input在dim轴上的 Shape 大小。上述参数约束在 C 侧有对应的运行时校验逻辑见 gather.cppvoid CheckGatherParamsInvalid(const Tensor params, const Tensor indices, int axis, const std::string opName) { const auto supportedTypes ConfigManager::Instance().GetOpSupportedInputDtypes(Opcode::OP_GATHER); CheckTensorDataType(params.GetStorage(), supportedTypes, opName); CheckFp8ArchSupport(params, opName); std::unordered_setDataType indexSupportedTypes {DT_INT32, DT_INT64}; CheckTensorDataType(indices.GetStorage(), indexSupportedTypes, opName); CheckTensorDimRange(params.GetStorage(), 1, NUM_VALUE_4, opName); // input 维度 1~4 CheckTensorDimRange(indices.GetStorage(), 1, NUM_VALUE_2, opName); // index 维度 1~2 CheckTensorShapeSize(params.GetStorage(), opName); CheckTensorShapeSize(indices.GetStorage(), opName); CheckAxisRange(params, axis); CheckTensorsFormatConsistency(params.GetStorage(), indices.GetStorage(), opName); }返回值说明返回输出 Tensor输出 Tensor 的数据类型与input保持一致输出 Tensor 的 Shape 由input、dim以及index共同确定具体规则为input.shape[:dim] index.shape input.shape[dim1:]dim为负数时先做归一化处理。由于index支持 1~2 维当index为 2 维、形状为 $(I_0, I_1)$ 时结果形状为 $(S_0, \ldots, S_{d-1}, I_0, I_1, S_{d1}, \ldots, S_{n-1})$即input的dim轴被index的完整形状整体替换。仓库中 calc_torch.cpp 提供了基于 PyTorch 的参考计算实现CPU 侧数值参考可用来核对结果的正确性。约束说明使用该接口前必须满足以下约束否则可能导致结果错误或 AI Core Error索引类型与取值index必须是整数类型DT_INT32 或 DT_INT64且元素值为合法索引即不能超出input.shape[dim]。维度取值范围dim为 int 类型取值范围-input.dim dim input.dim。支持负数负值会被解释为dim input.dim。C 侧同样有归一化与越界检查见 gather.cpp。viewshape 约束索引轴不可切input.shape的dim轴 viewshape 不可切要求viewshape[dim] input.shape[dim]其余维度的 Shape 大小不做限制。该约束来自 index_select 的算子语义dim 轴作为索引源需要在当前 view 中整体可见而不是当前实现的额外限制。若 dim 轴按照小于input.shape[dim]的 viewshape 切分index可能引用当前 view 之外的数据导致结果精度错误或 AI Core Error。在 C 切分实现中可以看到对params[axis]轴的处理正是不切分、offset 置 0、shape 取整轴见 gather.cpp// params[axis]不切 paramsInput.tileInfo.offset[axis] 0; paramsInput.tileInfo.shape[axis] paramsInput.tensor.GetShape()[axis];Tensor 数据类型说明input支持的数据类型按产品线区分Ascend 950PR / Ascend 950DTDT_INT8DT_INT16DT_INT32DT_UINT8DT_UINT16DT_UINT32DT_FP16DT_FP32DT_BF16DT_BOOLDT_FP8E4M3DT_FP8E5M2DT_FP8E8M0Atlas A3 训练系列产品 / Atlas A3 推理系列产品DT_INT8DT_INT16DT_INT32DT_UINT8DT_UINT16DT_UINT32DT_FP16DT_FP32DT_BF16Atlas A2 训练系列产品 / Atlas A2 推理系列产品DT_INT8DT_INT16DT_INT32DT_UINT8DT_UINT16DT_UINT32DT_FP16DT_FP32DT_BF16其中 FP8 类型DT_FP8E4M3、DT_FP8E5M2、DT_FP8E8M0仅支持 DAV_3510 架构该检查在 gather.cpp 中通过CheckFp8ArchSupport完成。TileShape 约束TileShape 的维度与 result 相同用于切分 result。TileShape 设置需保证 result 不超过 UB 大小具体用法详见 TileShape 设置示例。调用示例TileShape 设置示例调用该 operation 接口前应通过set_vec_tile_shapes设置 TileShape。TileShape 的维度设置须与输出张量保持一致用于控制输出 Tile 块的大小。以输入 $input[B,S,D]$、索引 $index[T]$、轴 $\text{axis}-2$即 S 轴、输出 $output[B,T,D]$ 为例设 TileShape 为 $[b_1, t_1, d_1]$该配置直接作用于输出 output 的各维度同时映射至输入与索引$b_1$ 切分 input 的批次维 B$d_1$ 切分 input 的特征维 D输入的序列维 S即轴 -2不参与切分仅作为索引源需保证 viewshape 覆盖完整的 S 轴对应约束 3$t_1$ 作用于索引 index 的长度维 T。Tile 内存占用须满足约束$$ b_1 \cdot t_1 \cdot d_1 \cdot \text{sizeof}(\mathbf{output}) \text{UBSize} $$也就是说每个 Tile 块的数据量必须能被统一缓冲区UB容纳设置 TileShape 时需要根据输出数据类型和 UB 容量综合评估。仓库中的系统测试 test_gather_onboard.py 展示了该接口与set_vec_tile_shapes、pypto.loop、pypto.assemble组合使用的典型算子内核模式先在 kernel 入口通过set_vec_tile_shapes设置切分块在循环中切片输入与索引调用pypto.index_select得到当前块的结果再用pypto.assemble将结果写回输出张量pypto.frontend.jit(debug_options{runtime_debug_mode: 0, compile_debug_mode: 0}) def gather_onboard_2d_2input_2d_output_kernel( input0: pypto.Tensor(), input1: pypto.Tensor(), output0: pypto.Tensor(), config: GatherOnboardConfig ): pypto.set_vec_tile_shapes(*config.tile_shape) for index_0 in pypto.loop(config.loop_ranges[0]): for index_1 in pypto.loop(config.loop_ranges[1]): offsets [index_0 * config.execution_view_shape[0], index_1 * config.execution_view_shape[1]] input0_view input0[:] input1_view input1[:] result pypto.index_select(input0_view, config.axis, input1_view) output_offset [ 0 if config.output_offset_map[axis] 0 else offsets[config.output_offset_map[axis]] for axis in range(2) ] pypto.assemble(result, output_offset, output0)接口调用示例x pypto.tensor([3, 4], pypto.DT_FP32) indices pypto.tensor([2], pypto.DT_INT32) out1 pypto.index_select(x, 0, indices) out2 pypto.index_select(x, 1, indices)结果示例如下输入x: [[ 0.1427, 0.0231, -0.5414, -1.0009], [-0.4664, 0.2647, -0.1228, -1.1068], [-1.1734, -0.6571, 0.7230, -0.6004]] 输入index: [0, 2] 输出out1: [[ 0.1427, 0.0231, -0.5414, -1.0009], [-1.1734, -0.6571, 0.7230, -0.6004]] 输出out2: [[ 0.1427, -0.5414], [-0.4664, -0.1228], [-1.1734, 0.7230]]示例解读out1 pypto.index_select(x, 0, indices)沿 0 轴行方向取第 0 行和第 2 行结果形状为[2, 4]out2 pypto.index_select(x, 1, indices)沿 1 轴列方向取第 0 列和第 2 列结果形状为[3, 2]。该示例同时出现在 indexing.py 的 docstring 中作为接口的官方行为参考。调用链与底层实现解析pypto.index_select的完整调用链为Python 前端 API → pybind11 绑定 → C tile_fwk 算子实现 → 图内 OP_GATHER/OP_GATHER_FROM_UB 算子。理解这条链路有助于定位问题、评估性能。1. Python 前端封装接口在 indexing.py 中定义经op_wrapper装饰后转发至底层实现op_wrapper def index_select(input: Tensor, dim: int, index: Tensor) - Tensor: ... return pypto_impl.index_select(input, dim, index)2. pybind11 绑定Python 侧的pypto_impl.index_select由 operation.cpp 绑定到 C 实现底层实际复用 Gather 算子m.def( index_select, [](const Tensor params, int dim, const Tensor indices) { return npu::tile_fwk::Gather(params, indices, dim); }, Tensor index_select.);3. C 算子实现C 入口 gather.cpp 的Gather在完成格式要求 TILEOP_NZ与参数合法性校验后进入GatherOperation执行 tiling 切分形状推导GatherOperationResultShapegather.cpp按替换 dim 轴规则计算结果形状递归切分TiledGatherOperationgather.cpp按照 result 的 TileShape 逐维递归切分三个分支分别处理 gather 轴外层、index 轴本身与 gather 轴内层并在叶子节点为每个 Tile 块插入OP_GATHER_FROM_UB静态形状或OP_GATHER动态形状算子同时设置axis属性动态形状路径TensorGatherOperationgather.cpp针对动态 Shape 场景通过GraphUtils::AddDynOperation添加带动态 valid shape 的OP_GATHER算子形状推断 Pass图内OP_GATHER/OP_GATHER_FROM_UB算子的形状推断函数为InferFunc4Gather注册于 op_infer_shape_impl.cpp同样遵循替换 dim 轴的规则保证图中下游算子拿到的输出形状与接口语义一致。4. 配套参考实现与测试数值参考calc_torch.cpp 提供基于 PyTorch 的 CPU 参考实现用于算子结果的数值校验golden 对照并支持 FP8/FP4 等低比特类型的格式转换处理系统测试test_gather_onboard.py 覆盖 2D/3D 输入、2D/3D/4D 输出等组合场景测试中通过与torch.index_select的 CPU 结果对比来校验pypto.index_select的正确性见 test_gather_onboard.py并覆盖了轴、切分循环、TileShape 等参数的不同配置。总结pypto.index_select是 CANN PyPTO 中实现按索引取数的核心算子接口其语义与 PyTorch 的torch.index_select对齐但在昇腾场景下需要额外关注三点索引轴 viewshape 不可切dim轴作为索引源必须在当前 view 中整体可见这是算子语义决定的硬性约束TileShape 必须与输出维度一致并保证单个 Tile 的内存占用小于 UB 容量数据类型按产品线区分FP8 类型仅限 DAV_3510 架构Ascend 950 系列。正确设置set_vec_tile_shapes并理解其与输入/索引/输出的映射关系是编写高性能、无越界错误的 index_select 内核的关键。【免费下载链接】pyptoPyPTO发音: pai p-t-oParallel Tensor/Tile Operation编程范式。项目地址: https://gitcode.com/cann/pypto创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/20 23:57:23

BCC 实战:用 eBPF SOCKET_FILTER 解析 HTTP 流量并提取 URL

eBPF可观测性性能剖析网络 【免费下载链接】bcc BCC - Tools for BPF-based Linux IO analysis, networking, monitoring, and more 项目地址: https://gitcode.com/gh_mirrors/bc/bcc 点击查看 免费下载 导读 本篇文章以 BCC 仓库中的 examples/networking/http_…

2026/9/20 23:57:23

Cline 实战:TaoToken 跑通 pytest 仓库的 test_skipping 回归用例

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 0:47:25

RAG技术优化:检索增强生成系统的关键策略与实践

1. RAG技术体系概述检索增强生成(Retrieval-Augmented Generation)作为当前NLP领域的前沿技术,通过将信息检索与文本生成相结合,有效解决了传统大语言模型的知识固化问题。我在实际项目中发现,标准的RAG流程通常包含四…

2026/9/21 0:47:25

Claude Code 桌面版接入 DeepSeek 与离线 Skills 安装全攻略

1. 为什么我要折腾这套组合:Claude Code 桌面版 DeepSeek 离线 Skills先说清楚这套东西到底是什么。Claude Code 是 Anthropic 推出的一个命令行 AI 编程助手,它跟普通聊天式 AI 最大的区别在于:它能直接读写你本地的项目文件、执行终端命令…

2026/9/21 0:47:25

QGIS等时圈分析实战:ORS插件Key申请与参数设置避坑指南

1. 等时圈分析与ORS插件到底在做什么等时圈分析这件事,说白了就是回答一个很朴素的问题:从某个点出发,在给定时间内,我到底能走到哪些地方。做城市规划的要拿它评估公共服务覆盖范围,做商业选址的要拿它算门店辐射半径…

2026/9/21 0:47:25

普通人用AI变现,第一个工具到底该怎么选?

我见过太多人,一听说AI能变现,第一反应就是到处问:现在哪个AI工具最强?哪个能不限次数白嫖?哪个生成的内容最像真人?然后就开始了一场漫长的工具测评之旅。各种官网、教程、对比帖收藏了上百篇,…

2026/9/21 0:47:25

JDK 17.0.8免安装版Windows配置指南:从下载到环境变量

简介:JDK 17.0.8 Windows免安装版为Java开发者提供开箱即用的开发环境,无需经过复杂安装流程,解压配置环境变量即可使用。作为长期支持(LTS)版本,它包含javac编译器、Java运行环境、javadoc文档生成器、jdb…

2026/9/21 0:42:24

Xilinx 7系列FPGA入门:从选型架构到时序约束实战要点

简介:面向FPGA初学者与嵌入式开发者的Xilinx 7系列FPGA入门介绍文档,以简明方式梳理系列整体定位与核心技术要点。内容涵盖Spartan-7、Artix-7、Kintex-7、Virtex-7四个子系列的适用场景、性能参数与功耗优势,详细对比单位功耗性价比、成本削…

2026/9/20 0:04:49

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/20 0:04:49

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/21 0:02:23

OpenResearch:构建可复现的开放式研究工作流

第一次看到“OpenResearch”这个名字,我脑子里冒出的不是某个具体软件,而更像一种研究方式的宣言:开放、可复现、可验证。这三件事放在一起,其实比大多数人想象中难得多。过去几年我一直在折腾自己的研究工作流,从纯纸…

2026/9/20 4:54:47

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/20 5:01:23

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/20 5:09:33

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码