当前位置: 首页 > news >正文

Ascend C关键分形格式详解

关键分形格式详解

【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit

矩阵分形存储格式是对多维Tensor在内存中数据排布格式的描述。

为了适配矩阵计算单元的物理读取路径,不同的产品形态有不同的格式要求:

  • Zz × Zn = Nz(A × B = C)组合
    矩阵乘法A × B = C要求:左矩阵A使用Zz格式,右矩阵B使用Zn格式,结果矩阵C使用Nz格式,如图1所示。这种分形格式组合适用于:

    • Atlas A2训练系列产品/Atlas A2推理系列产品
    • Atlas A3训练系列产品/Atlas A3推理系列产品
    • Atlas 200I/500 A2 推理产品
    • Atlas 推理系列产品
    • Atlas 训练系列产品
    • Kirin X90
    • Kirin 9030

    图1矩阵乘法场景涉及的数据格式
    ![](https://raw.gitcode.com/cann/asc-devkit/raw/1cd1d1192e01ae4a8684cd07552c35e13e5c4bdf/docs/zh/api/figures/fractals_involved_in_matrix_calculation_a2a3.png "矩阵乘法场景涉及的数据格式"?utm_source=gitcode_repo_files)

  • Nz × Zn = Nz(A × B = C)组合
    针对Ascend 950PR/Ascend 950DT,矩阵乘法C = A×B要求:左矩阵A使用Nz格式,右矩阵B使用Zn格式,结果矩阵C使用Nz格式,如图2所示:

    图2矩阵乘法场景涉及的数据格式
    ![](https://raw.gitcode.com/cann/asc-devkit/raw/1cd1d1192e01ae4a8684cd07552c35e13e5c4bdf/docs/zh/api/figures/fractals_involved_in_matrix_calculation_950.png "矩阵乘法场景涉及的数据格式-27"?utm_source=gitcode_repo_files)

在具体的矩阵乘法场景中,各格式的详细定义与物理成因如下:

ND格式(N-Dimension)

  • 定义:通用的N维张量格式,即“线性格式”;数据在内存中是连续线性的。
  • 场景:通常存在于Global Memory(GM)中。在进行矩阵运算前,通常需要将其转换为Nz格式以适配Cube单元。
  • 转换示例:从ND(GM)到Nz(L1 Buffer)的数据格式转换见图3,图中展示了一个具体的M=40,K=56的矩阵(数据类型为half),在从Global Memory(GM)搬运至L1 Buffer并转换为Nz格式时的内存排布变化:
    • 原始数据(ND格式):

      • 左侧GM中存储的是原始矩阵,shape为40 x 56。
      • 数据呈线性连续排布(图中长箭头所示),遵循row major(行主序)规则。
    • 对齐与填充(Padding):

      • 由于Cube单元的分形(Fractal)要求,目标矩阵必须能够被16 x 16的Block整除(假设数据类型为half,即32/sizeof(half)=16)。
      • M轴填充:原始M=40不能被16整除,需向上补齐至48(16 x 3)。
      • K轴填充:原始K=56不能被16整除,需向上补齐至64(16 x 4)。
      • 图中灰色区域即为补齐产生的无效数据(Padding),白色区域为原始有效数据。
    • 重排布(Nz格式):

      • 右侧L1 Buffer中,数据被重组为3 x 4个分形块。
      • Z字流动:每个16 x 16的小方块内部,以及方块之间,均按照特定的Z字形顺序存储(如图中折线箭头所示),完成了从“线性”到“分形”的物理映射,做好了进入Cube计算的准备。

图3ND(GM)到Nz(L1 Buffer)的数据转换

DN格式(Dimension-N)

  • 定义:通用的N维张量格式,其物理存储顺序对应于ND格式在内存维度上的转置排列,即ND遵循row major(行主序)规则,DN遵循column major(列主序)。列主序示意图如下所示:

  • 场景:通常存在于Global Memory(GM)中。若此输入要作为矩阵计算的输入,需要转换成Nz格式。
  • 转换示例:针对Ascend 950PR/Ascend 950DT,可以使用矩阵搬入DataCopy DN2NZ接口将其转换为Nz格式以适配Cube单元。

Zz格式(FRACTAL_Zz)

  • 定义:大Z外部row major(行主序)+ 小z内部row major(行主序),见图4。

    图4Zz格式(以half类型为例)

  • 物理位置:通常位于L0A Buffer,作为左矩阵。

  • 设计原理:

    • 行读取需求:在A×B中,A矩阵是被“横向扫描”的。
    • 内存一致性:Zz格式在微观上按行存储,这意味着A矩阵同一行的相邻元素在L0A Buffer的物理地址是连续的。Cube单元左侧通道可直接通过DMA连续读取,无需跨步(Stride)。
  • 格式转换过程:对一个Tensor的最低两维进行填充(pad)、拆分(reshape)和转置(transpose)。具体转换过程如下:

    (M, K)大小的矩阵被分为M1 * K1个分形,按照row major(行主序)排布,形状如Z字形;每个分形内部有M0 * K0个元素,按照row major(行主序)排布,形状如Z字形,所以这种数据格式称为Zz格式。其中,(M0, K0)表示一个分形的大小,分形Shape为16 x (32B / sizeof(Datatype)),大小为512字节。

    通过公式表达转换过程如下:

    (…, B, M, K)->pad->(…, B, M1 * M0, K1 * K0)->reshape->(…, B, M1, M0, K1, K0)->transpose->(…, B, M1, K1, M0, K0)
  • 分形大小约束:其中M0=16,而K0的大小取决于数据类型位宽:

    • 32-bit(float/int32):K0=8(分形16x8)
    • 16-bit(half):K0=16(分形16x16)
    • 8-bit(int8):K0=32(分形16x32)
    • 4-bit:K0=64(分形16x64)

Zn格式(FRACTAL_Zn)

  • 定义:大Z外部row major(行主序)+ 小n内部column major(列主序),见图5。

    图5Zn格式(以half类型为例)

  • 物理位置:

    • L0B Buffer:作为右乘矩阵。
    • L1 Buffer / GM:数据流转使用,一般用于保存离线处理好的右乘矩阵数据。
  • 设计原理:

    • 列读取需求:矩阵乘法需要取B矩阵的一列。若B矩阵为普通row major(行主序),同一列的数据在内存中会相隔整整一行,导致地址跳跃。
    • Zn的作用:Zn格式在分形内部强制按列存储。这意味着,B矩阵中逻辑上的一列数据,在L0B Buffer物理内存中被强行排在了一起,Cube单元只需线性读取即可天然获得B矩阵的列向量。
  • 格式转换过程:(K, N)大小的矩阵被分为K1 * N1个分形,按照row major(行主序)排布,形状如Z字形;每个分形内部有K0 * N0个元素,按照column major(列主序)排布,形状如N字形,所以这种数据格式称为Zn格式。其中,(N0,K0)表示一个分形的大小,分形shape为 16 x (32B / sizeof(Datatype)),大小为512字节。

    通过公式表达转换过程如下:

    (…, B, K, N)->pad->(…, B, K1 * K0, N1 * N0)->reshape->(…, B, K1, K0, N1, N0)->transpose->(…, B, K1, N1, N0, K0)
  • 分形大小约束:其中N0=16,而K0的大小同样取决于数据类型(规则同Zz格式),例如half类型下分形为16x16,int8下分形为16x32。

Nz格式(FRACTAL_Nz)

  • 定义:大N外部column major(列主序)+ 小z内部row major(行主序),见图6。

    图6Nz格式
    ![](https://raw.gitcode.com/cann/asc-devkit/raw/1cd1d1192e01ae4a8684cd07552c35e13e5c4bdf/docs/zh/api/figures/nz_fractals_of_half_for_cmatrix.png "Nz-格式"?utm_source=gitcode_repo_files)

  • 物理位置:

    • L0C Buffer:存储矩阵乘法的结果(分形固定为16x16)。
    • L1 Buffer / GM:数据流转的通用中间格式(分形为16xK0,K0的大小取决于数据类型位宽)。
    • L0A Buffer:仅Ascend 950PR/Ascend 950DT下使用,用于存储左矩阵(分形为16xK0,K0的大小取决于数据类型位宽)。
  • 设计原理:

    • Nz是昇腾芯片架构内部的“中间标准格式”。它是对“线性数据(ND)”和“计算专用数据(Zz/Zn)”的一种折中。
    • 大N排布(column major(列主序)Block)的设计通常是为了配合多核并行或后续算子(如Vector向量计算)在处理通道(Channel)维度数据时的便利性。

说明:通常情况下,Nz格式在L0C Buffer和L1 Buffer中分别用于不同的场景:

  • 在L0C Buffer中,Nz格式用于存储矩阵乘法的结果。其分形形状为16x16,包含256个元素,这种结构非常适合Cube计算单元进行高效的矩阵乘法运算。
  • 在L1 Buffer中,Nz格式被采用以便于将数据搬运到L0A Buffer和L0B Buffer时,能够方便地转换为对应的Zz和Zn格式。此时,分形形状为16 x (32B / sizeof(Datatype)),大小为512字节。 因此,当数据从L0C Buffer搬运到L1 Buffer时,其分形大小可能会发生变化。
  • 针对Ascend 950PR/Ascend 950DT,Nz格式在L0A Buffer中用于存储左矩阵。

Nz格式转换详解与示例

由于Nz格式是最常见的数据格式,我们以ND转Nz为例,详细说明数据格式转换过程。

  • 转换过程:(M,N)大小的矩阵被分为M1 * N1个分形,按照column major(列主序)排布,形状如N字形;每个分形内部有M0 * N0个元素,按照row major(行主序)排布,形状如Z字形,所以这种数据格式称为Nz格式。其中,(M0, N0)表示一个分形的大小。

  • 转换公式:

    (…, B, M, N)->pad->(…, B, M1 * M0, N1 * N0)->reshape->(…, B, M1, M0, N1, N0)->transpose->(…, B, N1, M1, M0, N0)
  • 转换示例:下面通过一个具体的例子来了解ND格式转换为Nz格式的过程。

    原始Tensor的Shape为(20, 28):

    data = [x for x in range(20 * 28)] data_a = data * np.ones((20 * 28), dtype="float16") tensor_a = data_a.reshape((20, 28)) print(tensor_a)

    原始Tensor数据打印如下:

    [[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27.] ... [532. 533. 534. 535. 536. 537. 538. 539. 540. 541. 542. 543. 544. 545. 546. 547. 548. 549. 550. 551. 552. 553. 554. 555. 556. 557. 558. 559.]]

    转换过程通过伪代码表达如下:

    N0 = 16 N1 = (28 + N0 - 1) // N0 pad_n = N1 * N0 - 28 M0 = 16 M1 = (20 + M0 - 1) // M0 pad_m = M1 * M0 - 20 tensor_b = np.pad(tensor_a, [[0, pad_m], [0, pad_n]]) tensor_b = tensor_b.reshape((M1, M0, N1, N0)) tensor_b = tensor_b.transpose((2, 0, 1, 3)) print(tensor_b)

    转换过程示意图如下:

转换后Tensor打印如下: ```py [[[[ 0. 1. 2. ... 13. 14. 15.] [ 28. 29. 30. ... 41. 42. 43.] [ 56. 57. 58. ... 69. 70. 71.] ... [ 0. 0. 0. ... 0. 0. 0.] [ 0. 0. 0. ... 0. 0. 0.] [ 0. 0. 0. ... 0. 0. 0.]]] [[[ 16. 17. 18. ... 0. 0. 0.] [ 44. 45. 46. ... 0. 0. 0.] [ 72. 73. 74. ... 0. 0. 0.] ... [ 0. 0. 0. ... 0. 0. 0.] [ 0. 0. 0. ... 0. 0. 0.] [ 0. 0. 0. ... 0. 0. 0.]]]] ```

NC1HWC0格式

定义:NC1HWC0是一种用于卷积加速的数据格式。通过将NHWC数据在C维度进行split,变成C1份NHWC0,然后将C1份NHWC0在内存中连续排列,变成NC1HWC0。

C0固定为32Byte,C1=C/C0,如果结果不整除,最后一份数据需要padding到C0。

图7NHWC->NC1HWC0
![](https://raw.gitcode.com/cann/asc-devkit/raw/1cd1d1192e01ae4a8684cd07552c35e13e5c4bdf/docs/zh/api/figures/nhwc2nc1hwc0.png "NHWC--NC1HWC0"?utm_source=gitcode_repo_files)

  • 物理位置:通常位于Global Memory(GM)或者L1 Buffer中,作为卷积的Feature Map输入。

  • 格式转换过程:通常使用随路转换-ND2NZ搬运(DataCopy)指令来进行NHWC格式到NC1HWC0格式的转换。

    通过二维数据排布变换表达格式转换过程:

【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.jsqmd.com/news/1202887/

相关文章:

  • 怎样高效升级TinyMCE:开发者的实战迁移方案与风险控制
  • 2026 SCI学术润色机构测评|5家主流平台实测,硕博科研人避坑必看! - 小艾学姐
  • 2026年塑料盲沟厂家/源头工厂:排水抗压性能与市政工程专业品牌解析 - 企业推荐官【官方】
  • 从零实现SHA256:C语言手撕哈希算法的核心逻辑
  • 【宝塔面板建站】02. 10分钟Windows宝塔面板的极速安装与初始化避坑指南(保姆级图文)
  • 多多开团助手|拼多多商家的自动化补单神器出评价 - 资讯在线
  • Mac Mouse Fix终极指南:让普通鼠标超越苹果触控板的专业解决方案
  • Howl编辑器核心功能深度解析:缓冲区、窗口与模式
  • 鸿蒙应用开发实战【93】— 实战短信批量导入完整流程
  • 2026年金属膨胀节制造厂家:江苏宝鑫来管道成套设备有限公司专业解读 - 企业推荐官【官方】
  • 核函数实战指南:线性、多项式与高斯核在SVM中的选择与调优
  • Java团队接入大模型,工程化落地比调API难得多
  • 7个高效CMake配置技巧:提升AzerothCore-WoTLK构建速度300%
  • Claude 3.5 Sonnet 接入 VS Code 实操指南
  • 如何在消费级GPU上快速生成高质量视频:HunyuanVideo-1.5完整实践指南
  • C++字符串分割split()实现:从基础到高性能优化
  • 终极BT下载加速指南:92个公共Tracker让你的下载速度提升300%
  • 2026 年现阶段,温宿有实力的户外泳池建造施工队推荐,别再租了!这套DIY方案颠覆传统泳池建造思维 - 行业推荐官【认证】
  • 如何让2015年老旧Mac免费升级到最新macOS系统?OpenCore Legacy Patcher终极指南
  • C++常量、指针与动态内存管理:从基础原理到实战避坑指南
  • Axure RP 9中继器构建无限级树形菜单【实战解析】
  • 如何快速使用Notion研究工具:多源信息整合的完整指南
  • x2nestos常见问题解答:新手必看的10个注意事项
  • codes外网访问实战:frp穿透8091端口与HTTPS全链路部署
  • C++循环展开与指令调度优化实战:从原理到性能提升50%
  • 2026年7月最新亨得利官方服务项目及价格查询|详细地址及24小时热线权威信息公告 - 亨得利官方
  • 亲身探访北京劳力士官方售后服务中心|服务热线及全部官方地址(2026年7月最新) - 劳力士官方服务中心
  • 湖北音响改装难题破解:武汉声动汽车音响的5大技术保障与3步服务流程,豪车音响改装/路虎音响改装,音响改装旗舰店哪个好 - 音响改装门店分享
  • 同人创作指南:时间回溯设定与系列作品创作技巧
  • OBS ShaderFilter插件安装与配置全攻略:解锁GPU着色器特效