尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

CANN pto-isa TGEMV 指令详解:基于 Tile 的矩阵向量乘(GEMV)语义、汇编语法与 C++ 内建接口实战

发布时间:2026/9/20 19:05:13

资讯中心
01
ARTICLE

CANN pto-isa TGEMV 指令详解:基于 Tile 的矩阵向量乘(GEMV)语义、汇编语法与 C++ 内建接口实战

CANN pto-isa TGEMV 指令详解:基于 Tile 的矩阵向量乘(GEMV)语义、汇编语法与 C++ 内建接口实战
人工智能指令集算子库CANNAscend【免费下载链接】pto-isaParallel Tile Operation (PTO) is a virtual instruction set architecture designed by Ascend CANN, focusing on tile-level operations. This repository offers high-performance, cross-platform tile operations across Ascend platforms.项目地址https://gitcode.com/cann/pto-isa点击查看免费下载导读TGEMVTile-based General Matrix-Vector multiplication是 CANN pto-isa 虚拟指令集中面向矩阵-向量乘GEMV的核心指令它在 Tile 层面将通用矩阵乘TMATMUL约束为M1的特殊形态广泛用于 GEMV 类算子、逐 token 线性变换以及需要沿 K 维累加的向量化计算场景。本文以 docs/isa/TGEMV.md 为主线结合 include/pto/common/pto_instr.hpp、include/pto/npu/a2a3/TMatmul.hpp、include/pto/npu/a5/TMatmulImpls.hpp 等源码与 CPU 测试用例完整讲解 TGEMV / TGEMV_ACC / TGEMV_BIAS 的数学语义、三层汇编语法、C 内建接口、数据布局约束及 Auto/Manual 两种编程模式的实战写法帮助你准确使用该指令并规避常见约束陷阱。TGEMV 指令定位M1 的 TMATMUL 特化在 pto-isa 的指令体系中TMATMUL执行一般的矩阵乘C[M,N] A[M,K] * B[K,N]而TGEMV将矩阵乘法域限定为M 1左操作数 A 退化为单行矩阵一个行向量右操作数 B 保持为K × N矩阵输出 C 为单行的累加器 TileM 1K bMatrix.GetValidRow()N bMatrix.GetValidCol()这一约束在底层实现中被显式编码。例如 Atlas A2/A3 平台的 include/pto/npu/a2a3/TMatmul.hpp 中TGEMV_IMPL以模板参数1调用静态检查CheckStaticMadTileRes, TileLeft, TileRight, 1()随后以m 1调用底层TMatmulPTO_INTERNAL void TGEMV_IMPL(TileRes cMatrix, TileLeft aMatrix, TileRight bMatrix) { CheckStaticMadTileRes, TileLeft, TileRight, 1(); uint16_t k bMatrix.GetValidRow(); uint16_t n bMatrix.GetValidCol(); bool kDirectionAlign GetKDirectionAlign(aMatrix, bMatrix); PTO_ASSERT(k 1 k MMAD_MAX_SUPPORT_LENGTH, ERROR: The range of valid aMatrixCol is [1, 4095].); PTO_ASSERT(n 1 n MMAD_MAX_SUPPORT_LENGTH, ERROR: The range of valid bMatrixCol is [1, 4095].); TMatmulPhase, TileRes, TileLeft, TileRight, false, true, true( cMatrix.data(), aMatrix.data(), bMatrix.data(), 1, k, n, kDirectionAlign); }从源码结构看TGEMV是底层 MADMultiply-ADd硬件单元在m1情形下的直接映射它复用与TMATMUL完全相同的流水路径仅通过m1与不同的模板标志位如累加、偏置开关区分行为。这意味着凡是在性能模型costmodel中出现的TMATMUL相关延迟模型对TGEMV同样具有参考价值。三种指令形态的数学语义1. TGEMV基础矩阵-向量乘对于有效矩阵乘法域内的每个输出元素0 j N$$\mathrm{C}{0,j} \sum{k0}^{K-1} \mathrm{A}{0,k} \cdot \mathrm{B}{k,j}$$输出 C 是全新的结果计算从零开始不读取旧值。2. TGEMV_ACC带累加的矩阵-向量乘对于0 j N$$\mathrm{C}{0,j} \gets \mathrm{C}{0,j} \sum_{k0}^{K-1} \mathrm{A}{0,k} \cdot \mathrm{B}{k,j}$$关键语义已有的C元素是融合乘加FMA序列的初始累加值硬件在累加器中直接叠加本次点积结果它不是先独立从零算完点积、再在最后把旧C加上去。这一差异在数值行为累加顺序与舍入上可能产生可观测的差别。TGEMV_ACC常用于沿 K 维切分大矩阵后的分段累加split-K例如在 CPU 测试 tests/cpu/st/testcase/tmatmul/tmatmul_kernel.cpp 中循环首轮用TGEMV写入后续轮次用TGEMV_ACC(cTile, cTile, aTile, bTile)在同一 Tile 上持续累加。3. TGEMV_BIAS带偏置的矩阵-向量乘对于0 j N$$\mathrm{C}{0,j} \mathrm{Bias}{0,j} \sum_{k0}^{K-1} \mathrm{A}{0,k} \cdot \mathrm{B}{k,j}$$注意对于TGEMV_BIAS精确的累加器行为包括偏置是否作为累加初值参与以及数据类型提升规则由目标平台/实现定义编写跨平台代码时不应假设偏置的注入时机。汇编语法从同步形式到 DPS 的完整链路TGEMV 指令族在 pto-isa 中体现为三个层次的语法形态。同步形式PTO Assembly%acc tgemv %a, %b : (!pto.tile..., !pto.tile...) - !pto.tile... %acc1 tgemv.acc %acc0, %a, %b : (!pto.tile..., !pto.tile..., !pto.tile...) - !pto.tile... %acc tgemv.bias %a, %b, %bias : (!pto.tile..., !pto.tile..., !pto.tile...) - !pto.tile...AS Level 1SSA 形式%c pto.tgemv %a, %b : (!pto.tile..., !pto.tile...) - !pto.tile... %c_out pto.tgemv.acc %c_in, %a, %b : (!pto.tile..., !pto.tile..., !pto.tile...) - !pto.tile... %c pto.tgemv.bias %a, %b, %bias : (!pto.tile..., !pto.tile..., !pto.tile...) - !pto.tile...SSA 形式下每个值都是不可变的 SSA 值tgemv.acc显式以%c_in作为输入、%c_out作为输出便于编译器的依赖分析与调度。AS Level 2DPS显式 ins/outs 形式pto.tgemv ins(%a, %b : !pto.tile_buf..., !pto.tile_buf...) outs(%c : !pto.tile_buf...) pto.tgemv.acc ins(%c_in, %a, %b : !pto.tile_buf..., !pto.tile_buf..., !pto.tile_buf...) outs(%c_out : !pto.tile_buf...) pto.tgemv.bias ins(%a, %b, %bias : !pto.tile_buf..., !pto.tile_buf..., !pto.tile_buf...) outs(%c : !pto.tile_buf...)DPS 形式直接对应硬件级的输入ins与输出outs资源约定操作数类型从!pto.tile变为!pto.tile_buf表示实际绑定的 Tile 缓冲资源。三种形式的操作数顺序完全一致tgemv为(a, b) - ctgemv.acc为(c_in, a, b) - c_outtgemv.bias为(a, b, bias) - c。C 内建接口与底层实现路径接口声明公共包含头为include/pto/pto-inst.hpp内部声明位于include/pto/common/pto_instr.hpptemplate typename TileRes, typename TileLeft, typename TileRight, typename... WaitEvents PTO_INST RecordEvent TGEMV(TileRes cMatrix, TileLeft aMatrix, TileRight bMatrix, WaitEvents... events); template typename TileRes, typename TileLeft, typename TileRight, typename... WaitEvents PTO_INST RecordEvent TGEMV_ACC(TileRes cOutMatrix, TileRes cInMatrix, TileLeft aMatrix, TileRight bMatrix, WaitEvents... events); template typename TileRes, typename TileLeft, typename TileRight, typename TileBias, typename... WaitEvents PTO_INST RecordEvent TGEMV_BIAS(TileRes cMatrix, TileLeft aMatrix, TileRight bMatrix, TileBias biasData, WaitEvents... events);三个接口均返回RecordEvent并接受可变参数WaitEvents... events用于跨流水pipe依赖同步。源码实现模板分派与 Phase 重载从 include/pto/common/pto_instr.hpp 可以看到每个接口都有两个重载默认重载不带AccPhase通过MAP_INSTR_IMPL宏分派到当前平台架构对应的实现Phase 重载带模板参数AccPhase Phase允许调用方显式指定累加阶段如AccPhase::Unspecified及目标平台支持的其他阶段直接调用TGEMV_IMPLPhase/TGEMV_ACC_IMPLPhase/TGEMV_BIAS_IMPLPhase。template typename TileRes, typename TileLeft, typename TileRight, typename... WaitEvents PTO_INST RecordEvent TGEMV(TileRes cMatrix, TileLeft aMatrix, TileRight bMatrix, WaitEvents... events) { detail::PtoWaitEvents(events...); MAP_INSTR_IMPL(TGEMV, cMatrix, aMatrix, bMatrix); return {}; }各平台在include/pto/npu/a2a3/TMatmul.hpp、include/pto/npu/a5/TMatmulImpls.hpp、include/pto/cpu/TMatmul.hpp等文件中提供对应实现。值得注意的差异点CPU 后端include/pto/cpu/TMatmul.hppTGEMV_IMPL、TGEMV_ACC_IMPL、TGEMV_BIAS_IMPL分别直接委托给TMATMUL_IMPL、TMATMUL_ACC_IMPL、TMATMUL_BIAS_IMPL其中 BIAS 版本在矩阵乘完成后逐元素把单行偏置加到 C 的每一行A2A3 后端include/pto/npu/a2a3/TMatmul.hpp额外通过GetKDirectionAlign(aMatrix, bMatrix)判断 K 方向对齐并将该信息传入底层TMatmul/TMatmulBiasA5/A6 后端include/pto/npu/a5/TMatmulImpls.hpp使用CheckMadValidTileRes, TileLeft, TileRight, 1()做统一静态检查运行时仅对k、n断言与文档中A5 不额外补充 m/k/n 运行时断言的说明一致。另外include/pto/common/pto_instr.hpp中还声明了 MX 量化变体TGEMV_MX带 scale 矩阵、支持 ACC/BIAS 组合供对 micro-scaling 格式有需求的场景使用本文不再展开。约束体系形状、位置、尺寸与数据类型通用形状与位置约束TGEMV / TGEMV_ACC / TGEMV_BIAS 均适用静态形状约束TileLeft::Rows TileRes::RowsTileLeft::Cols TileRight::RowsTileRight::Cols TileRes::ColsTile 位置约束TileLeft::Loc LeftTileRight::Loc RightTileRes::Loc Acc运行时有效尺寸约束m必须为1k和n取自bMatrix.GetValidRow()与bMatrix.GetValidCol()必须位于[1, 4095]TMATMUL的 Acc 步幅pitch约束同样适用Acc Tile 的 Rows 需与 MAD 按块列写入的行数ceil16(m)对 TGEMV 即ceil16(1)兼容参见 A2A3 实现中MadAccStrideCompatibleTileRes, MadRows()的静态断言include/pto/npu/a2a3/TMatmul.hpp。TGEMV / TGEMV_ACC 数据类型约束A2A3 平台实现检查支持的(CType, AType, BType)三元组(int32_t, int8_t, int8_t)(float, half, half)(float, float, float)(float, bfloat16_t, bfloat16_t)Ascend 950PR / Ascend 950DTA5实现检查累加器类型必须是int32_t或float若为int32_t要求AType int8_t且BType int8_t若为float支持half、bfloat16_t、float、选定的 fp8 组合以及hifloat8_t/hifloat8_t目标定义分形/布局约束被强制执行LeftLoc Left、!isRowMajor、SFractal RowMajorRightLoc Right、isRowMajor、SFractal ColMajorAccLoc Acc、!isRowMajor、SFractal RowMajorTGEMV_BIAS 附加约束偏置 Tile 的数据类型必须与TileRes::DType完全一致源码中通过static_assert(std::is_same_v...)在编译期强制偏置 Tile 必须配置为单行TileBias::Rows 1偏置 Tile 的位置必须为TileType::BiasA5 附加说明除上述 GEMV 约定外底层 Ascend 950PR / Ascend 950DT matmul 实现不会再单独补充一组显式的m/k/n运行时断言。实战示例Auto 与 Manual 两种编程模式以下示例均可在包含include/pto/pto-inst.hpp后直接编译运行。Auto 模式下 Tile 的物理地址与调度由编译器/运行时统一管理Manual 模式下需先用TASSIGN为每个 Tile 显式绑定资源地址。1. TGEMVAuto 模式#include pto/pto-inst.hpp using namespace pto; void example_auto() { using A TileLefthalf, 1, 16; using B TileRighthalf, 16, 16; using C TileAccfloat, 1, 16; A a; B b; C c; TGEMV(c, a, b); }2. TGEMV_ACCAuto 模式#include pto/pto-inst.hpp using namespace pto; void example_auto() { using A TileLefthalf, 1, 16; using B TileRighthalf, 16, 16; using C TileAccfloat, 1, 16; A a; B b; C c0, c1; TGEMV_ACC(c1, c0, a, b); }注意TGEMV_ACC的累加输入c0与输出c1是独立的模板参数虽然类型同为TileAccfloat, 1, 16测试中也可以像TGEMV_ACC(cTile, cTile, aTile, bTile)这样原地累加。3. TGEMV_BIASAuto 模式#include pto/pto-inst.hpp using namespace pto; void example_auto() { using A TileLefthalf, 1, 16; using B TileRighthalf, 16, 16; using Bias TileTileType::Bias, half, 1, 16; using C TileAccfloat, 1, 16; A a; B b; Bias bias; C c; TGEMV_BIAS(c, a, b, bias); }Bias显式使用TileTileType::Bias, half, 1, 16声明位置为Bias、数据类型half、单行 16 列满足上文全部附加约束。4. Manual 模式用 TASSIGN 显式绑定资源Manual 模式下每个 Tile 在使用前都必须绑定物理资源地址示例中0x1000、0x2000等为 Tile 资源基址#include pto/pto-inst.hpp using namespace pto; void example_manual() { using A TileLefthalf, 1, 16; using B TileRighthalf, 16, 16; using C TileAccfloat, 1, 16; A a; B b; C c; TASSIGN(a, 0x1000); TASSIGN(b, 0x2000); TASSIGN(c, 0x3000); TGEMV(c, a, b); }TGEMV_ACC与TGEMV_BIAS的手动版本与此同理分别需为c0/c1或bias额外分配地址// TGEMV_ACC manualc0 绑定 0x3000c1 绑定 0x4000 TASSIGN(a, 0x1000); TASSIGN(b, 0x2000); TASSIGN(c0, 0x3000); TASSIGN(c1, 0x4000); TGEMV_ACC(c1, c0, a, b); // TGEMV_BIAS manuala/bias/c 分别绑定 TASSIGN(a, 0x1000); TASSIGN(b, 0x2000); TASSIGN(bias, 0x3000); TASSIGN(c, 0x4000); TGEMV_BIAS(c, a, b, bias);汇编级示例Auto 与 Manual 模式的发射形式Auto 模式资源放置与调度完全交由编译器/运行时直接发射指令# Auto mode: compiler/runtime-managed placement and scheduling. %c pto.tgemv %a, %b : (!pto.tile..., !pto.tile...) - !pto.tile...Manual 模式发射指令前必须显式绑定资源可选地使用pto.tassign绑定 tile 操作数# Manual mode: resources must be bound explicitly before issuing the instruction. # Optional for tile operands: # pto.tassign %arg0, tile(0x1000) # pto.tassign %arg1, tile(0x2000) %c pto.tgemv %a, %b : (!pto.tile..., !pto.tile...) - !pto.tile...DPS 层面对应的发射形式%acc tgemv %a, %b : (!pto.tile..., !pto.tile...) - !pto.tile... # AS Level 2 (DPS) pto.tgemv ins(%a, %b : !pto.tile_buf..., !pto.tile_buf...) outs(%c : !pto.tile_buf...)测试与验证在真实内核中如何调用 TGEMV仓库的 CPU 单元测试提供了 TGEMV 与 TMATMUL 在同一内核中按m动态分支的典型用法。tests/cpu/st/testcase/tmatmul/tmatmul_kernel.cpp 中内核先通过TLOAD从全局内存加载 A/B 矩阵、TMOV搬入 Tile再根据validM是否为 1 决定走TGEMV还是TMATMULif constexpr (isBias) { GlobalDataSrc2 src2Global(src2); TLOAD(biasTile, src2Global); if constexpr (validM 1) { TGEMV_BIAS(cTile, aTile, bTile, biasTile); } else { TMATMUL_BIAS(cTile, aTile, bTile, biasTile); } } else { if constexpr (validM 1) { TGEMV(cTile, aTile, bTile); } else { TMATMUL(cTile, aTile, bTile); } }同文件的 split-K 循环tests/cpu/st/testcase/tmatmul/tmatmul_kernel.cpp则展示了TGEMV_ACC的原位累加用法首轮用TGEMV写入结果后续轮次用TGEMV_ACC(cTile, cTile, aTile, bTile)持续累加这正是 GEMV 场景下沿 K 维分片求和的推荐写法。该测试文件同时也覆盖了tmatmul_layout、tmatmul_mx等布局与 MX 变体用例可作为编写新测试的参考模板。使用建议与注意事项何时用 TGEMV 而非 TMATMUL当矩阵乘的 M 维为 1向量 × 矩阵时直接使用TGEMV语义更精确也便于编译器按 GEMV 契约优化M 1 时应回退到TMATMUL。累加语义差异TGEMV_ACC的旧值是 FMA 序列的初始累加值而非独立点积的末尾加法对数值敏感性高的场景需关注累加顺序差异。偏置行为是平台相关的TGEMV_BIAS中偏置是否作为累加初值、数据类型提升规则由目标平台定义跨平台代码勿做强假设。静态断言尽早暴露错误形状、位置、数据类型、Bias 单行等约束多数在编译期通过static_assert检查运行时仅对k、n以及 A2A3 平台的部分动态尺寸做PTO_ASSERT因此把 Tile 类型写正确是使用 TGEMV 的第一道防线。跟随官方文档本文对应的完整指令说明见 docs/isa/TGEMV.md中文本见 docs/isa/TGEMV_zh.md指令总览与公共约定可参考 docs/isa/README.md 与 docs/isa/conventions.md。赞分享人工智能指令集算子库CANNAscend【免费下载链接】pto-isaParallel Tile Operation (PTO) is a virtual instruction set architecture designed by Ascend CANN, focusing on tile-level operations. This repository offers high-performance, cross-platform tile operations across Ascend platforms.项目地址https://gitcode.com/cann/pto-isa点击查看免费下载相关推荐如何快速掌握Netgen3D四面体网格生成的终极入门指南如何快速掌握Netgen3D四面体网格生成的终极入门指南 想要在有限元分析中获得高质量的网格吗Netgen作为一款强大的开源3D四面体网格生成器能够帮助您人工智能指令集算子库CANNAscendPTO-ISA TMULS 指令详解Tile 与标量逐元素乘法的语义、内建接口与实现原理PTO ISA TMULS 指令详解Tile 与标量逐元素乘法的语义、内建接口与实现原理 本文基于 CANN pto isa 仓库中 docs/isa/TMU人工智能指令集算子库CANNAscendCANN pto-isa TRELU 指令详解Tile 逐元素 ReLU 的语法、C 内建接口与跨平台实现CANN pto isa TRELU 指令详解Tile 逐元素 ReLU 的语法、C 内建接口与跨平台实现 本文以 CANN pto isa 仓库 doc人工智能指令集算子库CANNAscend上一篇programmer-book实战项目手把手教你构建企业级应用下一篇ACI.dev市场挑战商业化挑战分析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。