CANN/catlass LayoutTag(旧版Layout)

发布时间:2026/5/20 19:09:15

CANN/catlass LayoutTag(旧版Layout) LayoutTag旧版 Layout【免费下载链接】catlass本项目是CANN的算子模板库提供NPU上高性能矩阵乘及其相关融合类算子模板样例。项目地址: https://gitcode.com/cann/catlass本文介绍 CATLASS 中的LayoutTag即旧版 Layout 体系。概述LayoutTag是 CATLASS 早期版本的 Layout 实现定义在Catlass::layout命名空间下。与新版tla::Layout不同LayoutTag将布局类型和参数绑定为固定的结构体类型每种布局模式对应一个独立的 structLayoutTag说明RANKRowMajor行优先矩阵布局2ColumnMajor列优先矩阵布局2VectorLayout一维向量布局1zN分形内行优先、分形间列优先4nZ分形内列优先、分形间行优先4zZ分形内行优先、分形间行优先4nN分形内列优先、分形间列优先4PaddingRowMajor带填充的行优先分块布局4PaddingColumnMajor带填充的列优先分块布局4NDC1HWC05 维卷积张量布局5KDC1KHKWN1N0C04 维卷积权重布局4所有 LayoutTag 的代码位于include/catlass/layout/matrix.hpp、vector.hpp和tensor.hpp统一由include/catlass/layout/layout.hpp聚合引用。LayoutTag 与 tla::Layout 的关系LayoutTag是旧版设计tla::Layout是新版设计。两者通过以下机制桥接1.tla::MakeLayoutElement, LayoutTag新版推荐用法直接通过模板参数指定 LayoutTag 和元素类型来构造tla::Layoutauto layout tla::MakeLayoutElementA, Catlass::layout::RowMajor(m, k);内部同样根据 LayoutTag 类型分发构造对应的嵌套或非嵌套tla::Layout。这是实际开发中最常用的方式。2.tla::MakeLayoutFromTag定义在include/tla/layout.hpp将任意 LayoutTag 实例转换为tla::Layouttemplate class LayoutTag auto MakeLayoutFromTag(LayoutTag const tag);内部根据 LayoutTag 的具体类型提取其shape()和stride()构造对应的tla::LayoutRowMajor→LayoutShaperows, cols, Strideldm, _1ColumnMajor→LayoutShaperows, cols, Stride_1, ldmVectorLayout→LayoutShapelen, Stride_1zN/nZ→ 嵌套LayoutShapeShape..., Shape..., StrideStride..., Stride...3.Catlass::detail::TagToLayout定义在include/catlass/detail/tag_to_layout.hpp提供编译期类型映射将 LayoutTag 映射为对应的tla::Layout类型template class Element, class LayoutTag struct TagToLayout; // 特化示例 template class Element struct TagToLayoutElement, layout::RowMajor { using type tla::Layouttla::Shapeuint32_t, uint32_t, tla::Strideint64_t, tla::Int1; };对于分形布局zN、nZ、zZTagToLayout会根据Element类型计算ELE_NUM_PER_C0和ELE_NUM_PER_FRACTAL生成精确的嵌套 Layout 类型。关系总结LayoutTag (旧版) tla::Layout (新版) ───────────── ──────────────── RowMajor::MakeLayout(m, k) ────► MakeLayoutElement, RowMajor(m, k) │ │ └──── MakeLayoutFromTag() ──────────►┘ └──── TagToLayout ──────────►┘ (编译期类型映射)简而言之LayoutTag 是旧版的具体布局类型新版代码通过MakeLayoutElement, LayoutTag()使用 LayoutTag 作为标签来构造tla::Layout。通用接口所有 LayoutTag 都提供以下核心接口接口返回类型说明MakeLayoutElement(rows, cols)自身类型静态工厂方法根据元素类型和逻辑尺寸构造布局GetOffset(coord)LongIndex计算逻辑坐标对应的线性偏移GetTileLayout(tileShape)自身类型返回子 tile 的布局视图stride 继承自父布局shape()/shape(idx)Shape/Index获取布局的 shape可能包含分块结构stride()/stride(idx)Stride/LongIndex获取各维度的步长orgShape(idx)Index获取逻辑原始尺寸仅分形布局有此接口Capacity()LongIndex返回布局占用的总元素数各 LayoutTag 详解RowMajor — 行优先矩阵struct RowMajor { static constexpr int RANK 2; using Index uint32_t; using LongIndex int64_t; };行优先布局同一行内相邻列元素在内存中连续存放stride (ldm, 1)。构造方式// 默认构造stride 自动推导为 (cols, 1) RowMajor tag(rows, cols); // 指定 leading dimension RowMajor tag(rows, cols, ldm); // 通过 MakeLayout 工厂 auto tag RowMajor::MakeLayoutElement(rows, cols);GetOffset 计算offset row * stride[0] col即offset row * ldm col。可视化示例以 3×4 矩阵为例展示 RowMajor 的内存排布逻辑矩阵 (3 rows × 4 cols): col0 col1 col2 col3 row0: a00 a01 a02 a03 row1: a10 a11 a12 a13 row2: a20 a21 a22 a23 内存排布 (stride (4, 1))同一行内元素连续存放 地址: 0 1 2 3 4 5 6 7 8 9 10 11 ┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐ 数据: a00 a01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23 └────── row0 ──────┘ └────── row1 ──────┘ └────── row2 ──────┘ offset(row, col) row × 4 col 例如a12 位于 row1, col2 → offset 1×4 2 6ColumnMajor — 列优先矩阵struct ColumnMajor { static constexpr int RANK 2; using Index uint32_t; using LongIndex int64_t; };列优先布局同一列内相邻行元素在内存中连续存放stride (1, ldm)。构造方式ColumnMajor tag(rows, cols); // stride (1, rows) ColumnMajor tag(rows, cols, ldm); // stride (1, ldm) auto tag ColumnMajor::MakeLayoutElement(rows, cols);GetOffset 计算offset row col * stride[1]可视化示例以 3×4 矩阵为例展示 ColumnMajor 的内存排布逻辑矩阵 (3 rows × 4 cols): col0 col1 col2 col3 row0: a00 a01 a02 a03 row1: a10 a11 a12 a13 row2: a20 a21 a22 a23 内存排布 (stride (1, 3))同一列内元素连续存放 地址: 0 1 2 3 4 5 6 7 8 9 10 11 ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ 数据: a00 a10 a20 a01 a11 a21 a02 a12 a22 a03 a13 a23 └─── col0 ───┘ └─── col1 ───┘ └─── col2 ───┘ └─── col3 ───┘ offset(row, col) row col × 3 例如a12 位于 row1, col2 → offset 1 2×3 7VectorLayout — 一维向量struct VectorLayout { static constexpr int RANK 1; };用于 GEMV、Scale、Bias 等一维场景。stride固定为1。zN — 分形内行优先、分形间列优先struct zN { static constexpr int RANK 4; static constexpr int ORG_SHAPE_RANK 2; };zN是昇腾 CUBE 核最常用的内部数据格式之一。其排布规则为分形内部按行优先排布小方块内 row-major。分形之间按列优先排布分形块之间 col-major。Shape 结构为(rowsInFractal, rowsByFractal, colsInFractal, colsByFractal)即shape (C0_NUM_PER_FRACTAL, rowsRound / C0_NUM_PER_FRACTAL, ELE_NUM_PER_C0, colsRound / ELE_NUM_PER_C0)其中C0_NUM_PER_FRACTAL 16每个分形块的行数ELE_NUM_PER_C0BYTE_PER_C0 / sizeof(Element)每个 C0 单元的元素数ELE_NUM_PER_FRACTALBYTE_PER_FRACTAL / sizeof(Element)每个分形块的总元素数GetOffset 计算offset (row / rowsInFractal) * strideRowsByFractal (col / colsInFractal) * strideColsByFractal (row % rowsInFractal) * strideRowsInFractal (col % colsInFractal) * strideColsInFractal可视化示例为便于理解以简化参数演示C0_NUM_PER_FRACTAL2, ELE_NUM_PER_C02原始矩阵 4×6原始逻辑矩阵 (4 rows × 6 cols): col0 col1 col2 col3 col4 col5 row0: a00 a01 a02 a03 a04 a05 row1: a10 a11 a12 a13 a14 a15 row2: a20 a21 a22 a23 a24 a25 row3: a30 a31 a32 a33 a34 a35 Step 1 — 划分为 2×2 的分形块Fractal: [col0,col1] [col2,col3] [col4,col5] [r0,r1] ┌─────────┐ ┌─────────┐ ┌─────────┐ │ F00 │ │ F01 │ │ F02 │ [r2,r3] ├─────────┤ ├─────────┤ ├─────────┤ │ F10 │ │ F11 │ │ F12 │ └─────────┘ └─────────┘ └─────────┘ Step 2 — zN 排布规则分形间列优先分形内行优先 分形间列优先遍历顺序F00 → F10 → F01 → F11 → F02 → F12 每个分形内部行优先F00 [a00, a01, a10, a11] 内存排布 地址: 0 1 2 3 4 5 6 7 8 9 10 11 ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ 数据: a00 a01 a10 a11 a20 a21 a30 a31 a02 a03 a12 a13 └──── F00 ───┘ └──── F10 ───┘ └──── F01 ───┘ 12 13 14 15 16 17 18 19 20 21 22 23 ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ a22 a23 a32 a33 a04 a05 a14 a15 a24 a25 a34 a35 └──── F11 ───┘ └──── F02 ───┘ └──── F12 ───┘ 关键理解同一分形块内的元素在内存中连续分形块之间按列方向排列。 例如F00(第0行块,第0列块) 后紧跟 F10(第1行块,第0列块)而非 F01。nZ — 分形内列优先、分形间行优先与zN互为转置关系分形内部按列优先排布。分形之间按行优先排布。Shape 结构为(ELE_NUM_PER_C0, rowsRound / ELE_NUM_PER_C0, C0_NUM_PER_FRACTAL, colsRound / C0_NUM_PER_FRACTAL)。可视化示例使用与 zN 相同的原始矩阵和分形划分对比展示 nZ 的排布差异原始逻辑矩阵 (4 rows × 6 cols): col0 col1 col2 col3 col4 col5 row0: a00 a01 a02 a03 a04 a05 row1: a10 a11 a12 a13 a14 a15 row2: a20 a21 a22 a23 a24 a25 row3: a30 a31 a32 a33 a34 a35 Step 1 — 划分为 2×2 的分形块与 zN 相同: [col0,col1] [col2,col3] [col4,col5] [r0,r1] ┌─────────┐ ┌─────────┐ ┌─────────┐ │ F00 │ │ F01 │ │ F02 │ [r2,r3] ├─────────┤ ├─────────┤ ├─────────┤ │ F10 │ │ F11 │ │ F12 │ └─────────┘ └─────────┘ └─────────┘ Step 2 — nZ 排布规则分形间行优先分形内列优先 分形间行优先遍历顺序F00 → F01 → F02 → F10 → F11 → F12 每个分形内部列优先F00 [a00, a10, a01, a11] 内存排布 地址: 0 1 2 3 4 5 6 7 8 9 10 11 ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ 数据: a00 a10 a01 a11 a02 a12 a03 a13 a04 a14 a05 a15 └──── F00 ───┘ └──── F01 ───┘ └──── F02 ───┘ 12 13 14 15 16 17 18 19 20 21 22 23 ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ a20 a30 a21 a31 a22 a32 a23 a33 a24 a34 a25 a35 └──── F10 ───┘ └──── F11 ───┘ └──── F12 ───┘ 关键理解与 zN 相反分形块按行方向排列分形内部按列方向排列。 例如F00(第0行块,第0列块) 后紧跟 F01(第0行块,第1列块)而非 F10。zN 与 nZ 排布对比将同一矩阵分别用 zN 和 nZ 排布直观对比差异原始矩阵坐标 → 内存地址映射 元素 逻辑坐标 zN offset nZ offset a00 (row0,col0) 0 0 a01 (row0,col1) 1 2 a10 (row1,col0) 2 1 a11 (row1,col1) 3 3 a02 (row0,col2) 8 4 a12 (row1,col2) 10 6 a20 (row2,col0) 4 12 a30 (row3,col0) 6 13 zN: 分形间列优先 → 先遍历完第0列的所有分形块(F00,F10)再进入第1列(F01,F11) nZ: 分形间行优先 → 先遍历完第0行的所有分形块(F00,F01,F02)再进入第1行(F10,F11)zZ — 分形内行优先、分形间行优先分形内部按行优先排布。分形之间按行优先排布。适用于需要完全行优先访问的分形场景。nN — 分形内列优先、分形间列优先分形内部按列优先排布。分形之间按列优先排布。与zZ互为转置关系。四种分形布局对比布局分形内部分形之间典型用途zNRow-majorCol-majorCUBE 核 A 矩阵输入nZCol-majorRow-majorCUBE 核 B 矩阵输入zZRow-majorRow-major特殊排布场景nNCol-majorCol-major特殊排布场景PaddingRowMajor / PaddingColumnMajor针对非 512B 对齐场景设计的带填充布局通过分块方式提升访存效率PaddingRowMajor块内行优先块间行优先。PaddingColumnMajor块内列优先块间列优先。构造时需指定块大小blockRows和blockCols。NDC1HWC0 / KDC1KHKWN1N0C0卷积场景的专用高维布局定义在matrix.hpp末尾NDC1HWC0RANK5用于卷积输入特征图维度为(N, D, C1, H, W, C0)。KDC1KHKWN1N0C0RANK4用于卷积权重维度为(Kd*C1*Kh*Kw, N1, N0, C0)。实际使用示例以下示例来自examples/53_ascend950_fp8_mx_matmul/fp8_mx_matmul.cpp展示 LayoutTag 在 GEMM 算子中的典型用法步骤 1定义 LayoutTag 类型别名using LayoutTagA layout::RowMajor; using LayoutTagB layout::ColumnMajor; using LayoutTagC layout::RowMajor;步骤 2用 LayoutTag 构造实例用于内存分配和标杆计算LayoutTagA tagA LayoutTagA::MakeLayoutElementA(m, k); LayoutTagB tagB LayoutTagB::MakeLayoutElementB(k, n); LayoutTagC tagC LayoutTagC::MakeLayoutElementC(m, n); size_t lenA tagA.Capacity(); // 获取所需元素数量 size_t lenB tagB.Capacity(); size_t lenC tagC.Capacity();步骤 3用 LayoutTag 构造 tla::Layout用于 kernel 计算auto layoutA tla::MakeLayoutElementA, LayoutTagA(m, k); auto layoutB tla::MakeLayoutElementB, LayoutTagB(k, n); auto layoutC tla::MakeLayoutElementC, LayoutTagC(m, n);步骤 4将 LayoutTag 传递给 Tile 和 Kernelusing TileCopy Gemm::Tile::PackedMxTileCopyTla ArchTag, ElementA, LayoutTagA, ElementB, LayoutTagB, ...;LayoutTag 作为模板参数传递给 TileCopy 等组件使其在编译期确定数据搬运和计算的布局策略。与 tla::Layout 的选择建议场景推荐新编写的 kernel / tile 代码直接使用tla::Layout通过MakeLayout(shape, stride)构造需要兼容旧版 GEMM 框架使用 LayoutTag 作为模板参数内部通过MakeLayoutElement, LayoutTag()桥接到tla::Layout简单的矩阵乘法行优先 / 列优先两者均可LayoutTag 更简洁需要灵活自定义布局使用tla::LayoutLayoutTag 只支持固定的几种模式核心原则LayoutTag 是固定布局模式的快捷方式tla::Layout是通用的布局表达。新版代码推荐以tla::Layout为主LayoutTag 作为兼容层和便捷入口。【免费下载链接】catlass本项目是CANN的算子模板库提供NPU上高性能矩阵乘及其相关融合类算子模板样例。项目地址: https://gitcode.com/cann/catlass创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻