diff --git a/docs/isa/blockIntro/tma_block/header.md b/docs/isa/blockIntro/tma_block/header.md index d6ac466e..c180ccda 100644 --- a/docs/isa/blockIntro/tma_block/header.md +++ b/docs/isa/blockIntro/tma_block/header.md @@ -5,7 +5,7 @@ The header of the data transfer block needs to define which data transfer operat ## Assembly format ```asm -TileOp , SrcTile0<.reuse>, ..., SrcTile7<.reuse>, DepSrc0, DepSrc1, DepSrc2, [BGetList], +TileOp , SrcTile0<.reuse>, ..., SrcTile7<.reuse>, DepSrc, [BGetList], ->DstTile0, ..., DstTile3, [BSetList], DepDst ``` @@ -24,7 +24,7 @@ Each parameter is explained as follows: | **TileSize0, ..., TileSize3** | Indicates the space size of each output Tile register respectively. The parameter can be passed through a `立即数` or `全局寄存器`. | Depends on DstTile | | **[BGetList]** | Global register [GGPR](../../register/common/ggpr.md) input list. | Yes | | **[BSetList]** | Global register [GGPR](../../register/common/ggpr.md) output list. | Yes | -| **DepSrc0, DepSrc1, DepSrc2** | Up to three dependency-source slots that refer to previous block-instruction outputs to `D`. | Yes | +| **DepSrc** | Indicates the dependence of this block instruction on the previous block instruction output to D. | Yes | | **DepDst** | Indicates the barrier of this block instruction to the block instruction that references this identifier in subsequent sequences. | Yes | ## Encoding method @@ -42,7 +42,7 @@ A complete data transfer block instructionheader needs to be split into the foll - [B.IOR](../../header/B.IOR.md) `RegSrc0, RegSrc1, RegSrc2, ->RegDst0` -... - [B.IOR](../../header/B.IOR.md) `RegSrc9, RegSrc10, RegSrc11, ->RegDst4` -- [B.IOD](../../header/B.IOD.md) `DepSrc0, DepSrc1, DepSrc2, ->DepDst` +- [B.IOD](../../header/B.IOD.md) `DepSrc, ->DepDst` Among them, the encoding format of the BSTART.TMA instruction is as follows:![BSTART.TMA](../../../figs/bitfield/svg/BlockHeader_32bit/BSTART.TMA.svg) @@ -56,8 +56,8 @@ Among them, the function field is used to encode specific TileOp information. Th | 3 | - | Reserved | | 4 | [MGATHER](../../header/tileblock/MGATHER.md) | Gather data in discrete memory space into Tile registers. | | 5 | [MSCATTER](../../header/tileblock/MSCATTER.md) | Store the data in the Tile register into discrete memory space. | -| 6 | [MGATHER.MASK](../../header/tileblock/MGATHER.MASK.md) | Masked memory gather. Reads only lanes whose mask bit is set. | -| 7 | [MSCATTER.MASK](../../header/tileblock/MSCATTER.MASK.md) | Masked memory scatter. Writes only lanes whose mask bit is set. | +| 6 | [MGATHER.MASK](../../header/tileblock/MGATHER.MASK.md) | Masked memory gather, only gathers when the corresponding mask bit is 1. | +| 7 | [MSCATTER.MASK](../../header/tileblock/MSCATTER.MASK.md) | Masked memory scatter, only scatters when the corresponding mask bit is 1. | | 8-31 | Temporarily reserved | The DataType field is encoded as follows: @@ -71,4 +71,4 @@ The DataType field is encoded as follows: | 4 | FP16 | 12 | e1m2x2 | 20 | S4x2 | 28 | U4x2 | | 5 | BF16 | 13 | e8m0 | 21 | reserve | 29 | reserve | | 6 | HiF8 | 14 | HiF4x2 | 22 | reserve | 30 | reserve | -| 7 | e4m3 | 15 | reserve | 23 | reserve | 31 | invalid | +| 7 | e4m3 | 15 | reserve | 23 | reserve | 31 | invalid | \ No newline at end of file diff --git a/docs/zh/isa/blockIntro/tma_block/header.md b/docs/zh/isa/blockIntro/tma_block/header.md index 97d0ff7b..d9fcd927 100644 --- a/docs/zh/isa/blockIntro/tma_block/header.md +++ b/docs/zh/isa/blockIntro/tma_block/header.md @@ -5,7 +5,7 @@ ## 汇编格式 ```asm -TileOp , SrcTile0<.reuse>, ..., SrcTile7<.reuse>, DepSrc0, DepSrc1, DepSrc2, [BGetList], +TileOp , SrcTile0<.reuse>, ..., SrcTile7<.reuse>, DepSrc, [BGetList], ->DstTile0, ..., DstTile3, [BSetList], DepDst ``` @@ -24,7 +24,7 @@ TileOp , SrcTile0<.reuse>, ..., SrcTile7 | **TileSize0, ..., TileSize3** | 分别指示每个输出Tile寄存器的空间大小,可以通过一个 `立即数`或者`全局寄存器`传参。 | 取决于DstTile | | **[BGetList]** | 全局寄存器[GGPR](../../register/common/ggpr.md)输入列表。 | 是 | | **[BSetList]** | 全局寄存器[GGPR](../../register/common/ggpr.md)输出列表。 | 是 | -| **DepSrc0, DepSrc1, DepSrc2** | 表示本块指令最多显式记录 3 个前序 `D` 依赖槽位。 | 是 | +| **DepSrc** | 表示本块指令对前序输出至D的块指令的依赖。 | 是 | | **DepDst** | 表示本块指令对后序引用该标识的块指令的屏障。 | 是 | ## 编码方式 @@ -42,7 +42,7 @@ TileOp , SrcTile0<.reuse>, ..., SrcTile7 - [B.IOR](../../header/B.IOR.md) `RegSrc0, RegSrc1, RegSrc2, ->RegDst0` - ... - [B.IOR](../../header/B.IOR.md) `RegSrc9, RegSrc10, RegSrc11, ->RegDst4` -- [B.IOD](../../header/B.IOD.md) `DepSrc0, DepSrc1, DepSrc2, ->DepDst` +- [B.IOD](../../header/B.IOD.md) `DepSrc, ->DepDst` 其中,BSTART.TMA指令的编码格式如下: @@ -58,8 +58,8 @@ TileOp , SrcTile0<.reuse>, ..., SrcTile7 | 3 | - | 保留 | | 4 | [MGATHER](../../header/tileblock/MGATHER.md) | 将离散的内存空间中的数据聚集到Tile寄存器中。 | | 5 | [MSCATTER](../../header/tileblock/MSCATTER.md) | 将Tile寄存器中的数据存储到离散的内存空间。 | -| 6 | [MGATHER.MASK](../../header/tileblock/MGATHER.MASK.md) | 带掩码的内存聚集,仅当 MaskTile 中对应标志位为 1 时才执行聚集。 | -| 7 | [MSCATTER.MASK](../../header/tileblock/MSCATTER.MASK.md) | 带掩码的内存分散,仅当 MaskTile 中对应标志位为 1 时才执行分散。 | +| 6 | [MGATHER.MASK](../../header/tileblock/MGATHER.MASK.md) | 带掩码的内存聚集,仅当MaskTile中对应标志位为1时才执行聚集。 | +| 7 | [MSCATTER.MASK](../../header/tileblock/MSCATTER.MASK.md) | 带掩码的内存分散,仅当MaskTile中对应标志位为1时才执行分散。 | | 8-31 | 暂时保留 | DataType字段编码方式如下: diff --git a/docs/zh/isa/header/tileblock/MGATHER.MASK.md b/docs/zh/isa/header/tileblock/MGATHER.MASK.md index 00f53df2..ae07f76d 100644 --- a/docs/zh/isa/header/tileblock/MGATHER.MASK.md +++ b/docs/zh/isa/header/tileblock/MGATHER.MASK.md @@ -4,14 +4,13 @@ **带掩码的内存聚集(Masked Gather from Memory to Tile)** -`MGATHER.MASK` 是 `MGATHER` 的掩码变体,在其间接寻址聚集语义的基础上 -增加了逐元素谓词控制。除基地址寄存器(`RegSrc`)和偏移量 Tile -(`SrcTile`)外,该指令额外接受一个掩码 Tile(`MaskTile`),其中每个 -元素为 1 bit 的标志位,与 `SrcTile` 中的 offset 一一对应。 +`MGATHER.MASK` 是 `MGATHER` 的掩码变体,在其间接寻址聚集语义的基础上增加了逐元素谓词控制。除基地址寄存器(`RegSrc`)和偏移量 Tile(`SrcTile`)外,该指令额外接受一个掩码 Tile(`MaskTile`),其中每个元素为 1 bit 的标志位,与 SrcTile 中的 offset 一一对应。 -当掩码位为 `1` 时,硬件从 `baseAddress + offset` 读取一个 `DataType` -元素并写入 `DstTile`;当掩码位为 `0` 时,硬件跳过该位置的访存,并向 -目标位置写入 `PadValue`。 +执行时,对于 SrcTile 中位于 `(i, j)` 处的 offset 值 `off`,硬件首先检查 MaskTile 对应位置的掩码位: +- 若掩码为 `1`,则执行聚集操作:从内存地址 `baseAddress + off` 处读取一个 `DataType` 类型的数据元素,写入 DstTile 的 `(i, j)` 位置; +- 若掩码为 `0`,则跳过该位置,不产生内存访问,DstTile 的 `(i, j)` 位置写入 `PadValue` 填充值。 + +这一机制允许软件通过掩码动态控制哪些内存位置参与聚集,适用于需要条件性数据收集的场景(如稀疏矩阵中仅加载非零元素对应的数据)。 ## 汇编语法 @@ -23,48 +22,65 @@ MGATHER.MASK , SrcTile<.reuse>, MaskTile<. | 参数 | 说明 | 是否可选 | |------|-----|-----------| -| **Col** | Tile 中数据的列数,也是输入 Tile 中 offset 的列数。通过 `LB0` 传入。 | 否 | -| **Row** | Tile 中数据的行数,也是输入 Tile 中 offset 的行数。通过 `LB1` 传入。 | 是,默认为 1 | +| **Col** | Tile寄存器中数据的列数,也是输入Tile中offset的列数。该值可以通过全局寄存器[GGPR](../../register/common/ggpr.md)加`立即数`的方式进行设置,并存储到LB0寄存器。 | 否 | +| **Row** | Tile寄存器中数据的行数,也是输入Tile中offset的行数。该值可以通过全局寄存器[GGPR](../../register/common/ggpr.md)加`立即数`的方式进行设置,并存储到LB1寄存器。 | 是,默认为1 | | **DataType** | 从内存中收集的元素的数据类型/格式。 | 否 | -| **PadValue** | 掩码为 `0` 时写入目标 Tile 的填充值。可选值为 `Null`、`Zero`、`Max`、`Min`。 | 是,默认 `Null` | -| **RegSrc** | 输入全局寄存器 GGPR,用于存储收集数据的内存基地址 `baseAddress`。 | 否 | -| **SrcTile** | 输入 Tile 寄存器,用于存储一组基于 `baseAddress` 的偏移量。 | 否 | -| **MaskTile** | 输入 Tile 寄存器,用于存储 1 bit 掩码。 | 否 | -| **DstTile** | 输出 Tile 寄存器,用于存储聚集得到的数据。 | 否 | -| **Size** | 输出 Tile 的大小,必须等于 `Row * Col * sizeof(DataType)`。 | 否 | +| **PadValue** | DstTile 中掩码为 `0` 的位置的填充值。可选类型包括:`Null`(不填充或保留随机值)、`Zero`(填充零值)、`Max`(填充当前数据格式下的最大值)、`Min`(填充当前数据格式下的最小值)。 | 是,默认 Null | +| **RegSrc** | 输入全局寄存器GGPR,用于存储收集数据的内存基地址baseAddress。 | 否 | +| **SrcTile** | 输入Tile 寄存器,用于存储一组基于baseAddress的偏移(offset)。 | 否 | +| **MaskTile** | 输入Tile 寄存器,用于存储掩码标志位。每个元素为1bit,值为`1`表示对应offset有效,执行聚集操作;值为`0`表示对应offset无效,跳过聚集。 | 否 | +| **DstTile** | 输出Tile 寄存器,用于存储聚集得到的数据。 | 否 | +| **Size** | 指示输出Tile寄存器的大小。该值等于Row * Col * sizeof(DataType) | 否 | + +其中DataType的可选类型如下表: + +| 数据位宽 | 类型列表 | +|----------|------------| +| b64 | S64, U64, FP64 | +| b32 | S32, U32, FP32, TF32, HF32 | +| b16 | S16, U16, FP16, BF16 | +| b8 | S8, U8, FP8(E4M3, E5M2), E8M0, HiF8, HiF4x2, E1M2x2, E2M1x2, S4x2, U4x2 | -`SrcTile` 中 offset 的位宽由写入该 Tile 时使用的元素位宽决定,规范形式 -支持 `u16`、`u32` 和 `u64`。 +--- ## 编码格式 -该 TileOp 编码为以下指令: +该TileOp编码为以下指令: - [BSTART.TMA](../../blockIntro/tma_block/header.md) `MGATHER.MASK, DataType` -- [B.DATR](../../header/B.DATR.md) `PadValue` *(可选)* -- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB0` *(`Col`)* -- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB1` *(`Row`)* +- [B.DATR](../../header/B.DATR.md) `PadValue` *(注:可缺省该指令)* +- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB0` *(注:Col)* +- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB1` *(注:Row)* - [B.IOT](../../header/B.IOT.md) `SrcTile<.reuse>, MaskTile<.reuse>, last, ->DstTile` -- [B.IOR](../../header/B.IOR.md) `RegSrc` +- [B.IOR](../../header/B.IOR.md) `RegSrc` *(注:base)* + +--- ## 执行模型 +本指令执行过程通过伪代码示意如下: + ```c -void MGATHER_MASK(Tile dst, Scalar base, Tile src, Tile mask) { - for (int i = 0; i < Row; ++i) { - for (int j = 0; j < Col; ++j) { +// dst:用于存储聚集数据的输出Tile +// base: 收集数据的基地址 +// src: 存储离散的地址偏移的输入Tile +// mask: 存储掩码标志位的输入Tile,1bit/元素 +void MGATHER_MASK(Tile __out__ dst, Scalar __in__ base, Tile __in__ src, Tile __in__ mask) { + for (int i = 0; i < Row; i++) + for (int j = 0; j < Col; j++) { if (mask[i][j] == 1) { - offset_t offset = src[i][j]; + offset_t offset = src[i][j]; // offset宽度由src的元素位宽决定(u64/u32/u16) dst[i][j] = Memory[base + offset]; } else { - dst[i][j] = PadValue; + dst[i][j] = PadValue; // 掩码为0的位置写入PadValue } } - } } ``` ## 注意事项 -- `MaskTile` 按每元素 1 bit 解释。 -- 掩码为 `0` 的位置不产生访存。 +- `Size` 必须等于 `Row * Col * sizeof(DataType)`。 +- 输入数据块(SrcTile)中 `[0, Row) × [0, Col)` 范围内的所有 offset 元素均参与聚集操作。 +- SrcTile 中 offset 的位宽取决于写入该 Tile 时的元素位宽定义,支持 **u64**、**u32** 或 **u16** 格式,硬件根据 SrcTile 的实际元素位宽进行解析。 +- 输入掩码Tile(MaskTile)中每个元素为 **1 bit**,与 SrcTile 的 `[0, Row) × [0, Col)` 区域一一对应。掩码值为 `1` 时执行对应位置的聚集,为 `0` 时跳过该位置,不产生内存访问,对应位置写入 `PadValue` 填充值。 diff --git a/docs/zh/isa/header/tileblock/MGATHER.md b/docs/zh/isa/header/tileblock/MGATHER.md index e28e37f4..7cf8d19b 100644 --- a/docs/zh/isa/header/tileblock/MGATHER.md +++ b/docs/zh/isa/header/tileblock/MGATHER.md @@ -4,14 +4,9 @@ **内存聚集(Gather from Memory to Tile)** -`MGATHER` 是一条基于间接寻址的数据聚集指令。它以基地址寄存器 -(`RegSrc`)为内存起始地址,以输入 Tile(`SrcTile`)中存储的一组偏移量 -(offset)为索引,从离散的内存位置逐一读取数据元素,并按 offset 在 -`SrcTile` 中的行列顺序连续写入输出 Tile(`DstTile`)的对应位置,从而将 -稀疏分布的内存数据聚合为稠密的二维 Tile 数据块。 +`MGATHER` 是一条基于间接寻址的数据聚集指令。它以基地址寄存器(`RegSrc`)为内存起始地址,以输入 Tile(`SrcTile`)中存储的一组偏移量(offset)为索引,从离散的内存位置逐一读取数据元素,并按 offset 在 SrcTile 中的行列顺序连续写入输出 Tile(`DstTile`)的对应位置,从而将稀疏分布的内存数据聚合为稠密的二维 Tile 数据块。 -该指令只对 `[0, validRow) x [0, validCol)` 的有效区域执行访存;超出有效 -区域的输出位置写入 `PadValue`。 +该指令的核心语义可以理解为:对于 SrcTile 中位于 `(i, j)` 处的 offset 值 `off`,从内存地址 `baseAddress + off` 处读取一个 `DataType` 类型的数据元素,并将其写入 DstTile 的 `(i, j)` 位置。这一过程遍历 `validRow × validCol` 的有效区域,逐元素独立执行。 ## 汇编语法 @@ -23,51 +18,71 @@ MGATHER , SrcTile<.reus | 参数 | 说明 | 是否可选 | |------|-----|-----------| -| **validCol** | 有效列数,表示输出 Tile 中有效数据的列数,也是输入 Tile 中有效 offset 的列数。该值通过 `LB0` 传入。 | 否 | -| **validRow** | 有效行数,表示输出 Tile 中有效数据的行数,也是输入 Tile 中有效 offset 的行数。该值通过 `LB1` 传入。 | 是,默认为 1 | -| **Col** | 输出 Tile 每行的物理列数(包含填充列)。该值通过 `LB2` 传入。 | 是,默认等于 `validCol` | -| **Row** | 输出 Tile 的物理行数(包含填充行)。硬件通过 `Size / (Col * sizeof(DataType))` 自动推导。 | 否(硬件推导) | +| **validCol** | 有效列数,表示输出Tile中有效数据的列数,也是输入Tile中有效offset的列数。该值可以通过全局寄存器[GGPR](../../register/common/ggpr.md)加`立即数`的方式进行设置,并存储到LB0寄存器。 | 否 | +| **validRow** | 有效行数,表示输出Tile中有效数据的行数,也是输入Tile中有效offset的行数。该值可以通过全局寄存器[GGPR](../../register/common/ggpr.md)加`立即数`的方式进行设置,并存储到LB1寄存器。 | 是,默认为1 | +| **Col** | 输出Tile寄存器中一行元素的总列数(包含无效列)。该值可以通过全局寄存器[GGPR](../../register/common/ggpr.md)加`立即数`的方式进行设置,并存储到LB2寄存器。 | 是,默认等于validCol | +| **Row** | 输出Tile寄存器中一列的总行数(包含无效行)。该值由硬件通过 `TileSize / (Col * sizeof(DataType))` 计算得到,无需软件显式设置。 | 否(硬件推导) | | **DataType** | 从内存中收集的元素的数据类型/格式。 | 否 | -| **PadValue** | DstTile 中位于有效区域之外的填充值。可选值为 `Null`、`Zero`、`Max`、`Min`。 | 是,默认 `Null` | -| **RegSrc** | 输入全局寄存器 GGPR,用于存储收集数据的内存基地址 `baseAddress`。 | 否 | -| **SrcTile** | 输入 Tile 寄存器,用于存储一组基于 `baseAddress` 的偏移量。 | 否 | -| **DstTile** | 输出 Tile 寄存器,用于存储聚集得到的数据。 | 否 | -| **Size** | 输出 Tile 的大小,必须等于 `Row * Col * sizeof(DataType)`。 | 否 | +| **PadValue** | DstTile 中位于有效区域之外的填充值。可选类型包括:`Null`(不填充或保留随机值)、`Zero`(填充零值)、`Max`(填充当前数据格式下的最大值)、`Min`(填充当前数据格式下的最小值)。 | 是,默认 Null | +| **RegSrc** | 输入全局寄存器GGPR,用于存储收集数据的内存基地址baseAddress。 | 否 | +| **SrcTile** | 输入Tile 寄存器,用于存储一组基于baseAddress的偏移(offset)。 | 否 | +| **DstTile** | 输出Tile 寄存器,用于存储聚集得到的数据。 | 否 | +| **Size** | 指示输出Tile寄存器的大小。该值等于Row * Col * sizeof(DataType) | 否 | -`SrcTile` 中 offset 的位宽由写入该 Tile 时使用的元素位宽决定,规范形式 -支持 `u16`、`u32` 和 `u64`。 +其中DataType的可选类型如下表: + +| 数据位宽 | 类型列表 | +|----------|------------| +| b64 | S64, U64, FP64 | +| b32 | S32, U32, FP32, TF32, HF32 | +| b16 | S16, U16, FP16, BF16 | +| b8 | S8, U8, FP8(E4M3, E5M2), E8M0, HiF8, HiF4x2, E1M2x2, E2M1x2, S4x2, U4x2 | + +--- ## 编码格式 -该 TileOp 编码为以下指令: +该TileOp编码为以下指令: - [BSTART.TMA](../../blockIntro/tma_block/header.md) `MGATHER, DataType` -- [B.DATR](../../header/B.DATR.md) `PadValue` *(可选)* -- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB0` *(`validCol`)* -- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB1` *(`validRow`)* -- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB2` *(`Col`,可选)* +- [B.DATR](../../header/B.DATR.md) `PadValue` *(注:可缺省该指令)* +- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB0` *(注:validCol)* +- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB1` *(注:validRow)* +- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB2` *(注:Col,可缺省该指令)* - [B.IOT](../../header/B.IOT.md) `SrcTile<.reuse>, last, ->DstTile` -- [B.IOR](../../header/B.IOR.md) `RegSrc` +- [B.IOR](../../header/B.IOR.md) `RegSrc` *(注:base)* + +--- ## 执行模型 +本指令执行过程通过伪代码示意如下: + ```c -void MGATHER(Tile dst, Scalar base, Tile src) { - for (int i = 0; i < Row; ++i) { - for (int j = 0; j < Col; ++j) { +// dst:用于存储聚集数据的输出Tile +// base: 收集数据的基地址 +// src: 存储离散的地址偏移的输入Tile +void MGATHER(Tile __out__ dst, Scalar __in__ base, Tile __in__ src) { + for (int i = 0; i < Row; i++) + for (int j = 0; j < Col; j++) { if (i < validRow && j < validCol) { - offset_t offset = src[i][j]; + offset_t offset = src[i][j]; // offset宽度由src的元素位宽决定(u64/u32/u16) dst[i][j] = Memory[base + offset]; } else { - dst[i][j] = PadValue; + dst[i][j] = PadValue; // 填充区域写入PadValue } } - } } ``` +图示如下: + +![MGATHER](../../../figs/isa/tileop/MGATHER.png){ width="800" } + ## 注意事项 -- `validCol <= Col`,`validRow <= Row`。 -- `Size` 必须是 `Col * sizeof(DataType)` 的整数倍。 -- 超出有效区域的位置不产生访存,直接写入 `PadValue`。 +- `validCol` 必须小于等于 `Col`,即有效列数不超过一行的总列数。 +- `validRow` 必须小于等于 `Row`,即有效行数不超过一列的总行数。 +- `Row` 由硬件根据 `Size / (Col * sizeof(DataType))` 自动推导,因此 `Size` 必须是 `Col * sizeof(DataType)` 的整数倍。 +- 输入数据块(SrcTile)中仅 `[0, validRow) × [0, validCol)` 范围内的 offset 元素参与聚集操作;DstTile 中超出该有效范围的填充区域写入 `PadValue`。 +- SrcTile 中 offset 的位宽取决于写入该 Tile 时的元素位宽定义,支持 **u64**、**u32** 或 **u16** 格式,硬件根据 SrcTile 的实际元素位宽进行解析。 diff --git a/docs/zh/isa/header/tileblock/MSCATTER.MASK.md b/docs/zh/isa/header/tileblock/MSCATTER.MASK.md index fac9f460..e3952746 100644 --- a/docs/zh/isa/header/tileblock/MSCATTER.MASK.md +++ b/docs/zh/isa/header/tileblock/MSCATTER.MASK.md @@ -4,14 +4,13 @@ **带掩码的内存分散(Masked Scatter from Tile to Memory)** -`MSCATTER.MASK` 是 `MSCATTER` 的掩码变体,在其间接寻址分散语义的基础上 -增加了逐元素谓词控制。除基地址寄存器(`RegSrc`)、数据 Tile -(`SrcTile0`)和偏移量 Tile(`SrcTile1`)外,该指令额外接受一个掩码 -Tile(`MaskTile`),其中每个元素为 1 bit 的标志位。 +`MSCATTER.MASK` 是 `MSCATTER` 的掩码变体,在其间接寻址分散语义的基础上增加了逐元素谓词控制。除基地址寄存器(`RegSrc`)、数据 Tile(`SrcTile0`)和偏移量 Tile(`SrcTile1`)外,该指令额外接受一个掩码 Tile(`MaskTile`),其中每个元素为 1 bit 的标志位,与 SrcTile0/SrcTile1 中的元素一一对应。 -当掩码位为 `1` 时,硬件从 `SrcTile1` 读取偏移量 `off`,并将 -`SrcTile0` 的数据写入 `baseAddress + off`;当掩码位为 `0` 时,硬件跳过 -该位置的写入。 +执行时,对于 `(i, j)` 位置,硬件首先检查 MaskTile 对应位置的掩码位: +- 若掩码为 `1`,则执行分散操作:从 SrcTile1 读取偏移量 `off`,将 SrcTile0 中 `(i, j)` 处的数据元素写入内存地址 `baseAddress + off`; +- 若掩码为 `0`,则跳过该位置,不产生内存访问。 + +这一机制允许软件通过掩码动态控制哪些位置的数据参与分散,适用于需要条件性数据写入的场景(如仅更新稀疏矩阵中的非零元素)。 ## 汇编语法 @@ -23,43 +22,62 @@ MSCATTER.MASK , SrcTile0<.reuse>, SrcTile1<.reuse>, | 参数 | 说明 | 是否可选 | |------|-----|-----------| -| **Col** | Tile 中数据和 offset 的列数。通过 `LB0` 传入。 | 否 | -| **Row** | Tile 中数据和 offset 的行数。通过 `LB1` 传入。 | 是,默认为 1 | -| **DataType** | 向内存中分散写入的元素的数据类型/格式。 | 否 | -| **RegSrc** | 输入全局寄存器 GGPR,用于存储分散数据的内存基地址 `baseAddress`。 | 否 | -| **SrcTile0** | 第一个输入 Tile 寄存器,用于存储源数据。 | 否 | -| **SrcTile1** | 第二个输入 Tile 寄存器,用于存储偏移量(offset)。 | 否 | -| **MaskTile** | 输入 Tile 寄存器,用于存储 1 bit 掩码。 | 否 | +| **Col** | Tile寄存器中数据的列数,也是输入Tile中offset的列数。该值可以通过全局寄存器[GGPR](../../register/common/ggpr.md)加`立即数`的方式进行设置,并存储到LB0寄存器。 | 否 | +| **Row** | Tile寄存器中数据的行数,也是输入Tile中offset的行数。该值可以通过全局寄存器[GGPR](../../register/common/ggpr.md)加`立即数`的方式进行设置,并存储到LB1寄存器。 | 是,默认为1 | +| **DataType** | 输入Tile中数据的格式,即向内存中散布的元素的数据类型/格式。 | 否 | +| **RegSrc** | 输入全局寄存器GGPR,用于存储分散数据的内存基地址baseAddress。 | 否 | +| **SrcTile0** | 第一个输入Tile 寄存器,用于存储源数据。 | 否 | +| **SrcTile1** | 第二个输入Tile 寄存器,用于存储偏移量(offset)。 | 否 | +| **MaskTile** | 输入Tile 寄存器,用于存储掩码标志位。每个元素为1bit,值为`1`表示对应位置执行分散操作;值为`0`表示跳过该位置,不产生内存访问。 | 否 | + +其中DataType的可选类型如下表: + +| 数据位宽 | 类型列表 | +|----------|------------| +| b64 | S64, U64, FP64 | +| b32 | S32, U32, FP32, TF32, HF32 | +| b16 | S16, U16, FP16, BF16 | +| b8 | S8, U8, FP8(E4M3, E5M2), E8M0, HiF8, HiF4x2, E1M2x2, E2M1x2, S4x2, U4x2 | -`SrcTile1` 中 offset 的位宽由写入该 Tile 时使用的元素位宽决定,规范形式 -支持 `u16`、`u32` 和 `u64`。 +--- ## 编码格式 -该 TileOp 编码为以下指令: +该TileOp编码为以下指令: - [BSTART.TMA](../../blockIntro/tma_block/header.md) `MSCATTER.MASK, DataType` -- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB0` *(`Col`)* -- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB1` *(`Row`)* -- [B.IOT](../../header/B.IOT.md) `SrcTile0<.reuse>, SrcTile1<.reuse>, MaskTile<.reuse>, last` -- [B.IOR](../../header/B.IOR.md) `RegSrc` +- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB0` *(注:Col)* +- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB1` *(注:Row)* +- [B.IOT](../../header/B.IOT.md) `SrcTile0<.reuse>, SrcTile1<.reuse>` +- [B.IOT](../../header/B.IOT.md) `MaskTile<.reuse>, last` +- [B.IOR](../../header/B.IOR.md) `RegSrc` *(注:base)* + +--- ## 执行模型 +本指令执行过程通过伪代码示意如下: + ```c -void MSCATTER_MASK(Tile src0, Scalar base, Tile src1, Tile mask) { - for (int i = 0; i < Row; ++i) { - for (int j = 0; j < Col; ++j) { +// src0: 存储数据的输入Tile +// base: 表示基地址的标量 +// src1: 存储偏移的输入Tile +// mask: 存储掩码标志位的输入Tile,1bit/元素 +void MSCATTER_MASK(Tile __in__ src0, Scalar __in__ base, Tile __in__ src1, Tile __in__ mask) { + for (int i = 0; i < Row; i++) + for (int j = 0; j < Col; j++) { if (mask[i][j] == 1) { - offset_t offset = src1[i][j]; + offset_t offset = src1[i][j]; // offset宽度由src1的元素位宽决定(u64/u32/u16) Memory[base + offset] = src0[i][j]; } } - } } ``` ## 注意事项 -- `MaskTile` 按每元素 1 bit 解释。 -- 如果多个有效元素映射到同一目标地址,最终值由实现定义。 +- SrcTile0 的大小必须等于 `Row * Col * sizeof(DataType)`。 +- 输入数据块(SrcTile0 和 SrcTile1)中 `[0, Row) × [0, Col)` 范围内的所有元素均参与分散操作。 +- SrcTile1 中 offset 的位宽取决于写入该 Tile 时的元素位宽定义,支持 **u64**、**u32** 或 **u16** 格式,硬件根据 SrcTile1 的实际元素位宽进行解析。 +- 输入掩码Tile(MaskTile)中每个元素为 **1 bit**,与 SrcTile0/SrcTile1 的 `[0, Row) × [0, Col)` 区域一一对应。掩码值为 `1` 时执行对应位置的分散,为 `0` 时跳过该位置,不产生内存访问。 +- 如果多个未被掩码屏蔽的元素映射到同一目标内存地址,最终值由实现定义。 diff --git a/docs/zh/isa/header/tileblock/MSCATTER.md b/docs/zh/isa/header/tileblock/MSCATTER.md index 96fef113..d29395b3 100644 --- a/docs/zh/isa/header/tileblock/MSCATTER.md +++ b/docs/zh/isa/header/tileblock/MSCATTER.md @@ -4,12 +4,9 @@ **内存分散(Scatter from Tile to Memory)** -`MSCATTER` 是 `MGATHER` 的逆操作,基于间接寻址将稠密的二维 Tile 数据分散 -写入离散的内存位置。它以基地址寄存器(`RegSrc`)为内存起始地址,以 -偏移量 Tile(`SrcTile1`)中的 offset 为索引,将数据 Tile(`SrcTile0`) -中的元素写入 `baseAddress + offset`。 +`MSCATTER` 是 `MGATHER` 的逆操作,基于间接寻址将稠密的二维 Tile 数据分散写入离散的内存位置。它以基地址寄存器(`RegSrc`)为内存起始地址,以偏移量 Tile(`SrcTile1`)中存储的偏移量(offset)为索引,将数据 Tile(`SrcTile0`)中的每个元素写入对应的内存地址 `baseAddress + off`。 -该指令只对 `[0, validRow) x [0, validCol)` 的有效区域执行写入。 +该指令的核心语义可以理解为:对于 `(i, j)` 位置,从 SrcTile1 读取偏移量 `off`,将 SrcTile0 中 `(i, j)` 处的数据元素写入内存地址 `baseAddress + off`。这一过程遍历 `validRow × validCol` 的有效区域,逐元素独立执行。 ## 汇编语法 @@ -21,44 +18,65 @@ MSCATTER , SrcTile0<.reuse>, SrcT | 参数 | 说明 | 是否可选 | |------|------|------------| -| **validCol** | 有效列数,表示输入数据 Tile 和 offset Tile 的有效列数。该值通过 `LB0` 传入。 | 否 | -| **validRow** | 有效行数,表示输入数据 Tile 和 offset Tile 的有效行数。该值通过 `LB1` 传入。 | 是,默认为 1 | -| **Col** | 输入 Tile 每行的物理列数(包含无效列)。该值通过 `LB2` 传入。 | 是,默认等于 `validCol` | -| **Row** | 输入 Tile 的物理行数(包含无效行)。硬件通过 `SrcTile0.Size / (Col * sizeof(DataType))` 自动推导。 | 否(硬件推导) | -| **DataType** | 向内存中写入的元素的数据类型/格式。 | 否 | -| **RegSrc** | 输入全局寄存器 GGPR,用于存储分散数据的内存基地址 `baseAddress`。 | 否 | -| **SrcTile0** | 第一个输入 Tile 寄存器,用于存储源数据。 | 否 | -| **SrcTile1** | 第二个输入 Tile 寄存器,用于存储偏移量(offset)。 | 否 | - -`SrcTile1` 中 offset 的位宽由写入该 Tile 时使用的元素位宽决定,规范形式 -支持 `u16`、`u32` 和 `u64`。 +| **validCol** | 有效列数,表示输入Tile中有效数据的列数,也是输入Tile中有效offset的列数。该值可以通过全局寄存器[GGPR](../../register/common/ggpr.md)加`立即数`的方式进行设置,并存储到LB0寄存器。 | 否 | +| **validRow** | 有效行数,表示输入Tile中有效数据的行数,也是输入Tile中有效offset的行数。该值可以通过全局寄存器[GGPR](../../register/common/ggpr.md)加`立即数`的方式进行设置,并存储到LB1寄存器。 | 是,默认为1 | +| **Col** | 输入Tile寄存器中一行元素的总列数(包含无效列)。该值可以通过全局寄存器[GGPR](../../register/common/ggpr.md)加`立即数`的方式进行设置,并存储到LB2寄存器。 | 是,默认等于validCol | +| **Row** | 输入Tile寄存器中一列的总行数(包含无效行)。该值由硬件通过 `SrcTile0的Size / (Col * sizeof(DataType))` 计算得到,无需软件显式设置。 | 否(硬件推导) | +| **DataType** | 输入Tile中数据的格式,即向内存中散布的元素的数据类型/格式。 | 否 | +| **RegSrc** | 输入全局寄存器GGPR,用于存储分散数据的内存基地址baseAddress。 | 否 | +| **SrcTile0** | 第一个输入Tile 寄存器,用于存储源数据。 | 否 | +| **SrcTile1** | 第二个输入Tile 寄存器,用于存储偏移量(offset)。 | 否 | + +其中DataType的可选类型如下表: + +| 数据位宽 | 类型列表 | +|----------|------------| +| b64 | S64, U64, FP64 | +| b32 | S32, U32, FP32, TF32, HF32 | +| b16 | S16, U16, FP16, BF16 | +| b8 | S8, U8, FP8(E4M3, E5M2), E8M0, HiF8, HiF4x2, E1M2x2, E2M1x2, S4x2, U4x2 | + +--- ## 编码格式 -该 TileOp 编码为以下指令: +该TileOp编码为以下指令: - [BSTART.TMA](../../blockIntro/tma_block/header.md) `MSCATTER, DataType` -- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB0` *(`validCol`)* -- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB1` *(`validRow`)* -- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB2` *(`Col`,可选)* +- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB0` *(注:validCol)* +- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB1` *(注:validRow)* +- [B.DIM](../../header/B.DIM.md) `reg, imm, ->LB2` *(注:Col)* - [B.IOT](../../header/B.IOT.md) `SrcTile0<.reuse>, SrcTile1<.reuse>, last` -- [B.IOR](../../header/B.IOR.md) `RegSrc` +- [B.IOR](../../header/B.IOR.md) `RegSrc` *(注:base)* + +--- ## 执行模型 +本指令执行过程通过伪代码示意如下: + ```c -void MSCATTER(Tile src0, Scalar base, Tile src1) { - for (int i = 0; i < validRow; ++i) { - for (int j = 0; j < validCol; ++j) { - offset_t offset = src1[i][j]; +// src0: 存储数据的输入Tile +// base: 表示基地址的标量 +// src1: 存储偏移的输入Tile +void MSCATTER(Tile __in__ src0, Scalar __in__ base, Tile __in__ src1) { + for (int i = 0; i < validRow; i++) + for (int j = 0; j < validCol; j++) { + offset_t offset = src1[i][j]; // offset宽度由src1的元素位宽决定(u64/u32/u16) Memory[base + offset] = src0[i][j]; } - } } ``` +实现示意图如下: + +![MSCATTER](../../../figs/isa/tileop/MSCATTER.png){ width="800" } + ## 注意事项 -- `validCol <= Col`,`validRow <= Row`。 -- `SrcTile0.Size` 必须是 `Col * sizeof(DataType)` 的整数倍。 -- 如果多个有效元素映射到同一目标地址,最终值由实现定义。 +- `validCol` 必须小于等于 `Col`,即有效列数不超过一行的总列数。 +- `validRow` 必须小于等于 `Row`,即有效行数不超过一列的总行数。 +- `Row` 由硬件根据 `SrcTile0的Size / (Col * sizeof(DataType))` 自动推导,因此 SrcTile0 的 Size 必须是 `Col * sizeof(DataType)` 的整数倍。 +- 输入数据块(SrcTile0 和 SrcTile1)中仅 `[0, validRow) × [0, validCol)` 范围内的元素参与分散操作,超出该范围的元素行为未定义。 +- SrcTile1 中 offset 的位宽取决于写入该 Tile 时的元素位宽定义,支持 **u64**、**u32** 或 **u16** 格式,硬件根据 SrcTile1 的实际元素位宽进行解析。 +- 如果多个元素映射到同一目标内存地址,最终值由实现定义。 diff --git a/docs/zh/isa/header/tileblock/intro.md b/docs/zh/isa/header/tileblock/intro.md index 590b9156..8ad00552 100644 --- a/docs/zh/isa/header/tileblock/intro.md +++ b/docs/zh/isa/header/tileblock/intro.md @@ -18,8 +18,8 @@ TMA类指令主要用于内存操作,包括数据的加载、存储、复制 | 0 | 3 | - | 保留 | | 0 | 4 | [MGATHER](./MGATHER.md) | 将离散的内存空间的数据聚集到Tile寄存器中 | | 0 | 5 | [MSCATTER](./MSCATTER.md)| 将Tile寄存器中的数据存储到离散的内存空间 | -| 0 | 6 | [MGATHER.MASK](./MGATHER.MASK.md) | 带掩码的内存聚集,仅当 MaskTile 中对应标志位为 1 时才执行聚集 | -| 0 | 7 | [MSCATTER.MASK](./MSCATTER.MASK.md) | 带掩码的内存分散,仅当 MaskTile 中对应标志位为 1 时才执行分散 | +| 0 | 6 | [MGATHER.MASK](./MGATHER.MASK.md) | 带掩码的内存聚集,仅当MaskTile中对应标志位为1时才执行聚集 | +| 0 | 7 | [MSCATTER.MASK](./MSCATTER.MASK.md)| 带掩码的内存分散,仅当MaskTile中对应标志位为1时才执行分散 | | 0 | 8-31 | - | 保留 | --- diff --git a/mkdocs.zh.yml b/mkdocs.zh.yml index bc8bae58..4e7202ef 100644 --- a/mkdocs.zh.yml +++ b/mkdocs.zh.yml @@ -1185,9 +1185,7 @@ nav: - TSTORE: isa/header/tileblock/TSTORE.md - TMOV: isa/header/tileblock/TMOV.md - MGATHER: isa/header/tileblock/MGATHER.md - - MGATHER.MASK: isa/header/tileblock/MGATHER.MASK.md - MSCATTER: isa/header/tileblock/MSCATTER.md - - MSCATTER.MASK: isa/header/tileblock/MSCATTER.MASK.md - 复杂操作: - THISTOGRAM: isa/header/tileblock/THISTOGRAM.md - 模版指令集: