| @@ -147,7 +147,7 @@ if (block_idx == 0) { | |||
| 147 | - 当前核在执行搬运任务前,会通过Scalar单元不断读取该信号量的值。如果信号量不等于1,当前核会进入阻塞等待状态;当检测到信号量等于1时,当前核会解除阻塞,开始执行自己的数据搬运或原子操作。为确保信号量等于1之前,当前核不会执行搬运指令,需要在搬运指令之前插入核内同步3。 | 147 | - 当前核在执行搬运任务前,会通过Scalar单元不断读取该信号量的值。如果信号量不等于1,当前核会进入阻塞等待状态;当检测到信号量等于1时,当前核会解除阻塞,开始执行自己的数据搬运或原子操作。为确保信号量等于1之前,当前核不会执行搬运指令,需要在搬运指令之前插入核内同步3。 |
| 148 | 148 | ||
| 149 | **图4** 一对核之间软件同步方案流程图 | 149 | **图4** 一对核之间软件同步方案流程图 |
| 150 | - | 150 | + |
| 151 | 151 | ||
| 152 | Scalar单元访问GM上的信号量,存在两种访问方式: | 152 | Scalar单元访问GM上的信号量,存在两种访问方式: |
| 153 | 153 | ||
| @@ -35,7 +35,7 @@ | |||
| 35 | 35 | ||
| 36 | **图1** DCache内存层次示意图 | 36 | **图1** DCache内存层次示意图 |
| 37 | 37 | ||
| 38 | - | 38 | + |
| 39 | 39 | ||
| 40 | asc_dcci接口用于解决上述一致性问题,其功能可以拆解为两部分: | 40 | asc_dcci接口用于解决上述一致性问题,其功能可以拆解为两部分: |
| 41 | 41 | ||
| @@ -186,7 +186,7 @@ PIPE_M | |||
| 186 | </table> | 186 | </table> |
| 187 | 该索引矩阵用于A矩阵的稠密化,根据索引矩阵从MatrixA中的4个元素中选择2个元素参与计算,如下图所示: | 187 | 该索引矩阵用于A矩阵的稠密化,根据索引矩阵从MatrixA中的4个元素中选择2个元素参与计算,如下图所示: |
| 188 | 188 | ||
| 189 | - | 189 | + |
| 190 | 190 | ||
| 191 | ## 调用示例 | 191 | ## 调用示例 |
| 192 | 192 | ||
| @@ -92,7 +92,7 @@ ND到Nz的格式转换如[图2](#nd2nz_conversion)所示。 | |||
| 92 | 92 | ||
| 93 | **图2** ND2Nz转换示意图<a id="nd2nz_conversion"></a> | 93 | **图2** ND2Nz转换示意图<a id="nd2nz_conversion"></a> |
| 94 | 94 | ||
| 95 | - | 95 | + |
| 96 | 96 | ||
| 97 | ## 返回值说明 | 97 | ## 返回值说明 |
| 98 | 98 | ||
| @@ -160,13 +160,13 @@ PIPE_MTE1 | |||
| 160 | 160 | ||
| 161 | **图2** feature map格式 | 161 | **图2** feature map格式 |
| 162 | 162 | ||
| 163 | -  | 163 | +  |
| 164 | 164 | ||
| 165 | - 对应的filter的格式如下图: | 165 | - 对应的filter的格式如下图: |
| 166 | 166 | ||
| 167 | **图3** filter的格式 | 167 | **图3** filter的格式 |
| 168 | 168 | ||
| 169 | -  | 169 | +  |
| 170 | 170 | ||
| 171 | 其中n为filter的个数,可以看出维度排布为(Hk,Wk,Ci,n),但是需要注意的是下图的格式还需要根据Mmad中B矩阵的格式转换。 | 171 | 其中n为filter的个数,可以看出维度排布为(Hk,Wk,Ci,n),但是需要注意的是下图的格式还需要根据Mmad中B矩阵的格式转换。 |
| 172 | 172 | ||
| @@ -174,7 +174,7 @@ PIPE_MTE1 | |||
| 174 | 174 | ||
| 175 | 实际操作中,由于存储空间或者计算能力限制,我们通常会将整个卷积计算分块,一次只搬运并计算一小块数据。 | 175 | 实际操作中,由于存储空间或者计算能力限制,我们通常会将整个卷积计算分块,一次只搬运并计算一小块数据。 |
| 176 | 176 | ||
| 177 | - | 177 | + |
| 178 | 178 | ||
| 179 | 对于L0A Buffer中的feature map来说有两种方案,水平分块和垂直分块。分别对应[asc_set_l13d_rpt](../cube_load_aux_config/asc_set_l13d_rpt.md)参数中rpt_mode的0和1。 | 179 | 对于L0A Buffer中的feature map来说有两种方案,水平分块和垂直分块。分别对应[asc_set_l13d_rpt](../cube_load_aux_config/asc_set_l13d_rpt.md)参数中rpt_mode的0和1。 |
| 180 | 180 | ||
| @@ -184,13 +184,13 @@ rpt_mode =0时,每次repeat会改变在filter窗口中读取数据点的位置 | |||
| 184 | 184 | ||
| 185 | **图5** rpt_mode = 0时的filter窗口 | 185 | **图5** rpt_mode = 0时的filter窗口 |
| 186 | 186 | ||
| 187 | - | 187 | + |
| 188 | 188 | ||
| 189 | rpt_mode =1的时候filter窗口中读取数据的位置保持不变,每个repeat在feature map中前进C0个元素。 | 189 | rpt_mode =1的时候filter窗口中读取数据的位置保持不变,每个repeat在feature map中前进C0个元素。 |
| 190 | 190 | ||
| 191 | **图6** rpt_mode = 1时的filter窗口 | 191 | **图6** rpt_mode = 1时的filter窗口 |
| 192 | 192 | ||
| 193 | - | 193 | + |
| 194 | 194 | ||
| 195 | ### 使用3D卷积数据搬运完成矩阵计算所需2D格式数据的搬运 | 195 | ### 使用3D卷积数据搬运完成矩阵计算所需2D格式数据的搬运 |
| 196 | 196 | ||
| @@ -120,17 +120,17 @@ PIPE_MTE1 | |||
| 120 | 120 | ||
| 121 | - 对应的feature map格式如下图: | 121 | - 对应的feature map格式如下图: |
| 122 | 122 | ||
| 123 | - | 123 | + |
| 124 | 124 | ||
| 125 | - 对应的filter的格式如下图: | 125 | - 对应的filter的格式如下图: |
| 126 | 126 | ||
| 127 | - | 127 | + |
| 128 | 128 | ||
| 129 | 其中n为filter的个数,可以看出维度排布为(Hk,Wk,Ci,n),但是需要注意的是下图的格式还需要根据Mmad中B矩阵的格式转换。 | 129 | 其中n为filter的个数,可以看出维度排布为(Hk,Wk,Ci,n),但是需要注意的是下图的格式还需要根据Mmad中B矩阵的格式转换。 |
| 130 | 130 | ||
| 131 | 实际操作中,由于存储空间或者计算能力限制,我们通常会将整个卷积计算分块,一次只搬运并计算一小块数据。 | 131 | 实际操作中,由于存储空间或者计算能力限制,我们通常会将整个卷积计算分块,一次只搬运并计算一小块数据。 |
| 132 | 132 | ||
| 133 | - | 133 | + |
| 134 | 134 | ||
| 135 | 对于L0A Buffer中的feature map来说有两种方案,水平分块和垂直分块。分别对应参数中repeatMode的0和1。 | 135 | 对于L0A Buffer中的feature map来说有两种方案,水平分块和垂直分块。分别对应参数中repeatMode的0和1。 |
| 136 | 136 | ||
| @@ -138,11 +138,11 @@ PIPE_MTE1 | |||
| 138 | 138 | ||
| 139 | repeatMode =0时,每次repeat会改变在filter窗口中读取数据点的位置,然后跳到下一个C0的位置。 | 139 | repeatMode =0时,每次repeat会改变在filter窗口中读取数据点的位置,然后跳到下一个C0的位置。 |
| 140 | 140 | ||
| 141 | - | 141 | + |
| 142 | 142 | ||
| 143 | repeatMode =1的时候filter窗口中读取数据的位置保持不变,每个repeat在feature map中前进C0个元素。 | 143 | repeatMode =1的时候filter窗口中读取数据的位置保持不变,每个repeat在feature map中前进C0个元素。 |
| 144 | 144 | ||
| 145 | - | 145 | + |
| 146 | 146 | ||
| 147 | ## 调用示例 | 147 | ## 调用示例 |
| 148 | 148 | ||
| @@ -41,7 +41,7 @@ | |||
| 41 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); | 41 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); |
| 42 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 | 42 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 |
| 43 | 43 | ||
| 44 | - | 44 | + |
| 45 | 45 | ||
| 46 | 如下图示例: | 46 | 如下图示例: |
| 47 | 47 | ||
| @@ -49,7 +49,7 @@ | |||
| 49 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 | 49 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 |
| 50 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 | 50 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 |
| 51 | 51 | ||
| 52 | - | 52 | + |
| 53 | 53 | ||
| 54 | - 对于half/bfloat16_t数据类型,每次迭代处理16 × 16 × 2B数据,可处理1个分形(一个分形512B),每次迭代中,源操作数中1个16 × 16分形将被转置。 | 54 | - 对于half/bfloat16_t数据类型,每次迭代处理16 × 16 × 2B数据,可处理1个分形(一个分形512B),每次迭代中,源操作数中1个16 × 16分形将被转置。 |
| 55 | - 因为每次迭代处理16 × 16 × 2B数据,需要3次迭代可以完成,repeat_time = 3; | 55 | - 因为每次迭代处理16 × 16 × 2B数据,需要3次迭代可以完成,repeat_time = 3; |
| @@ -57,7 +57,7 @@ | |||
| 57 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址无间隔; | 57 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址无间隔; |
| 58 | - 该场景下,因为其分形即为方块矩阵,每个迭代处理一个分形,不存在迭代内分形的间隔,该参数设置无效。 | 58 | - 该场景下,因为其分形即为方块矩阵,每个迭代处理一个分形,不存在迭代内分形的间隔,该参数设置无效。 |
| 59 | 59 | ||
| 60 | - | 60 | + |
| 61 | 61 | ||
| 62 | - 对于float/int32_t/uint32_t数据类型,每次迭代处理16 × 16 × 4B数据,可处理2个分形(一个分形512B),每次迭代中,源操作数2个连续的16 × 8分形将被合并为1个16 × 16的方块矩阵,基于方块矩阵做转置,转置后分裂为2个16 × 8分形,根据目的操作数分形间隔等参数可以有不同的排布。 | 62 | - 对于float/int32_t/uint32_t数据类型,每次迭代处理16 × 16 × 4B数据,可处理2个分形(一个分形512B),每次迭代中,源操作数2个连续的16 × 8分形将被合并为1个16 × 16的方块矩阵,基于方块矩阵做转置,转置后分裂为2个16 × 8分形,根据目的操作数分形间隔等参数可以有不同的排布。 |
| 63 | 如下图示例: | 63 | 如下图示例: |
| @@ -66,14 +66,14 @@ | |||
| 66 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); | 66 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); |
| 67 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为0(单位:512B)。 | 67 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为0(单位:512B)。 |
| 68 | 68 | ||
| 69 | - | 69 | + |
| 70 | 70 | ||
| 71 | 如下图示例: | 71 | 如下图示例: |
| 72 | - repeat_time和src_stride的解释和上图示例一致。 | 72 | - repeat_time和src_stride的解释和上图示例一致。 |
| 73 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 | 73 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 |
| 74 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为2(单位:512B)。 | 74 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为2(单位:512B)。 |
| 75 | 75 | ||
| 76 | - | 76 | + |
| 77 | 77 | ||
| 78 | 搬入前的数据排布参见[关键分形格式详解](../../cube_compute/cube_compute_fractal_intro/key_fractal_format_details.md);地址对齐与搬运粒度要求参见[矩阵计算输入搬运约束](cube_compute_input_move_constraint.md),并结合本接口的参数和约束说明使用。 | 78 | 搬入前的数据排布参见[关键分形格式详解](../../cube_compute/cube_compute_fractal_intro/key_fractal_format_details.md);地址对齐与搬运粒度要求参见[矩阵计算输入搬运约束](cube_compute_input_move_constraint.md),并结合本接口的参数和约束说明使用。 |
| 79 | 79 | ||
| @@ -117,17 +117,17 @@ PIPE_MTE1 | |||
| 117 | 117 | ||
| 118 | - 对应的feature map格式如下图: | 118 | - 对应的feature map格式如下图: |
| 119 | 119 | ||
| 120 | - | 120 | + |
| 121 | 121 | ||
| 122 | - 对应的filter的格式如下图: | 122 | - 对应的filter的格式如下图: |
| 123 | 123 | ||
| 124 | - | 124 | + |
| 125 | 125 | ||
| 126 | 其中n为filter的个数,可以看出维度排布为(Hk,Wk,Ci,n),但是需要注意的是下图的格式还需要根据Mmad中B矩阵的格式转换。 | 126 | 其中n为filter的个数,可以看出维度排布为(Hk,Wk,Ci,n),但是需要注意的是下图的格式还需要根据Mmad中B矩阵的格式转换。 |
| 127 | 127 | ||
| 128 | 实际操作中,由于存储空间或者计算能力限制,我们通常会将整个卷积计算分块,一次只搬运并计算一小块数据。 | 128 | 实际操作中,由于存储空间或者计算能力限制,我们通常会将整个卷积计算分块,一次只搬运并计算一小块数据。 |
| 129 | 129 | ||
| 130 | - | 130 | + |
| 131 | 131 | ||
| 132 | 对于L0B Buffer中的feature map来说有两种方案,水平分块和垂直分块。分别对应参数中repeatMode的0和1。 | 132 | 对于L0B Buffer中的feature map来说有两种方案,水平分块和垂直分块。分别对应参数中repeatMode的0和1。 |
| 133 | 133 | ||
| @@ -135,11 +135,11 @@ PIPE_MTE1 | |||
| 135 | 135 | ||
| 136 | repeatMode =0时,每次repeat会改变在filter窗口中读取数据点的位置,然后跳到下一个C0的位置。 | 136 | repeatMode =0时,每次repeat会改变在filter窗口中读取数据点的位置,然后跳到下一个C0的位置。 |
| 137 | 137 | ||
| 138 | - | 138 | + |
| 139 | 139 | ||
| 140 | repeatMode =1的时候filter窗口中读取数据的位置保持不变,每个repeat在feature map中前进C0个元素。 | 140 | repeatMode =1的时候filter窗口中读取数据的位置保持不变,每个repeat在feature map中前进C0个元素。 |
| 141 | 141 | ||
| 142 | - | 142 | + |
| 143 | 143 | ||
| 144 | ## 调用示例 | 144 | ## 调用示例 |
| 145 | 145 | ||
| @@ -41,7 +41,7 @@ | |||
| 41 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); | 41 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); |
| 42 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 | 42 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 |
| 43 | 43 | ||
| 44 | - | 44 | + |
| 45 | 45 | ||
| 46 | 如下图示例: | 46 | 如下图示例: |
| 47 | 47 | ||
| @@ -49,7 +49,7 @@ | |||
| 49 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 | 49 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 |
| 50 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 | 50 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 |
| 51 | 51 | ||
| 52 | - | 52 | + |
| 53 | 53 | ||
| 54 | - 对于half/bfloat16_t数据类型,每次迭代处理16 × 16 × 2B数据,可处理1个分形(一个分形512B),每次迭代中,源操作数中1个16 × 16分形将被转置。 | 54 | - 对于half/bfloat16_t数据类型,每次迭代处理16 × 16 × 2B数据,可处理1个分形(一个分形512B),每次迭代中,源操作数中1个16 × 16分形将被转置。 |
| 55 | - 因为每次迭代处理16 × 16 × 2B数据,需要3次迭代可以完成,repeat_time = 3; | 55 | - 因为每次迭代处理16 × 16 × 2B数据,需要3次迭代可以完成,repeat_time = 3; |
| @@ -57,7 +57,7 @@ | |||
| 57 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址无间隔; | 57 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址无间隔; |
| 58 | - 该场景下,因为其分形即为方块矩阵,每个迭代处理一个分形,不存在迭代内分形的间隔,该参数设置无效。 | 58 | - 该场景下,因为其分形即为方块矩阵,每个迭代处理一个分形,不存在迭代内分形的间隔,该参数设置无效。 |
| 59 | 59 | ||
| 60 | - | 60 | + |
| 61 | 61 | ||
| 62 | - 对于float/int32_t/uint32_t数据类型,每次迭代处理16 × 16 × 4B数据,可处理2个分形(一个分形512B),每次迭代中,源操作数2个连续的16 × 8分形将被合并为1个16 × 16的方块矩阵,基于方块矩阵做转置,转置后分裂为2个16 × 8分形,根据目的操作数分形间隔等参数可以有不同的排布。 | 62 | - 对于float/int32_t/uint32_t数据类型,每次迭代处理16 × 16 × 4B数据,可处理2个分形(一个分形512B),每次迭代中,源操作数2个连续的16 × 8分形将被合并为1个16 × 16的方块矩阵,基于方块矩阵做转置,转置后分裂为2个16 × 8分形,根据目的操作数分形间隔等参数可以有不同的排布。 |
| 63 | 如下图示例: | 63 | 如下图示例: |
| @@ -66,14 +66,14 @@ | |||
| 66 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); | 66 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); |
| 67 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为0(单位:512B)。 | 67 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为0(单位:512B)。 |
| 68 | 68 | ||
| 69 | - | 69 | + |
| 70 | 70 | ||
| 71 | 如下图示例: | 71 | 如下图示例: |
| 72 | - repeat_time和src_stride的解释和上图示例一致。 | 72 | - repeat_time和src_stride的解释和上图示例一致。 |
| 73 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 | 73 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 |
| 74 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为2(单位:512B)。 | 74 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为2(单位:512B)。 |
| 75 | 75 | ||
| 76 | - | 76 | + |
| 77 | 77 | ||
| 78 | 搬入前的数据排布参见[关键分形格式详解](../../cube_compute/cube_compute_fractal_intro/key_fractal_format_details.md);地址对齐与搬运粒度要求参见[矩阵计算输入搬运约束](cube_compute_input_move_constraint.md),并结合本接口的参数和约束说明使用。 | 78 | 搬入前的数据排布参见[关键分形格式详解](../../cube_compute/cube_compute_fractal_intro/key_fractal_format_details.md);地址对齐与搬运粒度要求参见[矩阵计算输入搬运约束](cube_compute_input_move_constraint.md),并结合本接口的参数和约束说明使用。 |
| 79 | 79 | ||
| @@ -40,21 +40,21 @@ | |||
| 40 | - src_stride = 1,表示相邻迭代间,源操作数前一个方块矩阵与后一个方块矩阵起始地址的间隔为1(单位:32 × 32 × 1B),这里的单位实际上是拼接后的方块矩阵的大小; | 40 | - src_stride = 1,表示相邻迭代间,源操作数前一个方块矩阵与后一个方块矩阵起始地址的间隔为1(单位:32 × 32 × 1B),这里的单位实际上是拼接后的方块矩阵的大小; |
| 41 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); | 41 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); |
| 42 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 | 42 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 |
| 43 | - | 43 | + |
| 44 | 44 | ||
| 45 | 如下图示例: | 45 | 如下图示例: |
| 46 | 46 | ||
| 47 | - repeat_time和src_stride的解释和上图示例一致。 | 47 | - repeat_time和src_stride的解释和上图示例一致。 |
| 48 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 | 48 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 |
| 49 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 | 49 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 |
| 50 | - | 50 | + |
| 51 | 51 | ||
| 52 | - 对于half/bfloat16_t数据类型,每次迭代处理16 × 16 × 2B数据,可处理1个分形(一个分形512B),每次迭代中,源操作数中1个16 × 16分形将被转置。 | 52 | - 对于half/bfloat16_t数据类型,每次迭代处理16 × 16 × 2B数据,可处理1个分形(一个分形512B),每次迭代中,源操作数中1个16 × 16分形将被转置。 |
| 53 | - 因为每次迭代处理16 × 16 × 2B数据,需要3次迭代可以完成,repeat_time = 3; | 53 | - 因为每次迭代处理16 × 16 × 2B数据,需要3次迭代可以完成,repeat_time = 3; |
| 54 | - src_stride = 1,表示相邻迭代间,源操作数前一个方块矩阵与后一个方块矩阵起始地址的间隔为1 (单位:16 × 16 × 2B); | 54 | - src_stride = 1,表示相邻迭代间,源操作数前一个方块矩阵与后一个方块矩阵起始地址的间隔为1 (单位:16 × 16 × 2B); |
| 55 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址无间隔; | 55 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址无间隔; |
| 56 | - 该场景下,因为其分形即为方块矩阵,每个迭代处理一个分形,不存在迭代内分形的间隔,该参数设置无效。 | 56 | - 该场景下,因为其分形即为方块矩阵,每个迭代处理一个分形,不存在迭代内分形的间隔,该参数设置无效。 |
| 57 | - | 57 | + |
| 58 | 58 | ||
| 59 | - 对于float/int32_t/uint32_t数据类型,每次迭代处理16 × 16 × 4B数据,可处理2个分形(一个分形512B),每次迭代中,源操作数2个连续的16 × 8分形将被合并为1个16 × 16的方块矩阵,基于方块矩阵做转置,转置后分裂为2个16 × 8分形,根据目的操作数分形间隔等参数可以有不同的排布。 | 59 | - 对于float/int32_t/uint32_t数据类型,每次迭代处理16 × 16 × 4B数据,可处理2个分形(一个分形512B),每次迭代中,源操作数2个连续的16 × 8分形将被合并为1个16 × 16的方块矩阵,基于方块矩阵做转置,转置后分裂为2个16 × 8分形,根据目的操作数分形间隔等参数可以有不同的排布。 |
| 60 | 如下图示例: | 60 | 如下图示例: |
| @@ -62,19 +62,19 @@ | |||
| 62 | - src_stride = 1,表示相邻迭代间,源操作数前一个方块矩阵与后一个方块矩阵起始地址的间隔为1(单位:16 × 16 × 4B),这里的单位实际上是拼接后的方块矩阵的大小; | 62 | - src_stride = 1,表示相邻迭代间,源操作数前一个方块矩阵与后一个方块矩阵起始地址的间隔为1(单位:16 × 16 × 4B),这里的单位实际上是拼接后的方块矩阵的大小; |
| 63 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); | 63 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); |
| 64 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为0(单位:512B)。 | 64 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为0(单位:512B)。 |
| 65 | - | 65 | + |
| 66 | 66 | ||
| 67 | 如下图示例: | 67 | 如下图示例: |
| 68 | - repeat_time和src_stride的解释和上图示例一致。 | 68 | - repeat_time和src_stride的解释和上图示例一致。 |
| 69 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 | 69 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 |
| 70 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为2(单位:512B)。 | 70 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为2(单位:512B)。 |
| 71 | - | 71 | + |
| 72 | 72 | ||
| 73 | - 对于int4b\_t数据类型,每次迭代处理64\*64\*0.5B数据,可处理4个分形(一个分形512B),每次迭代中,源操作数中4个连续的16\*64分形将被合并为1个64\*64的方块矩阵,基于方块矩阵做转置,转置后分裂为4个16\*64分形,根据目的操作数分形间隔等参数可以有不同的排布。 | 73 | - 对于int4b\_t数据类型,每次迭代处理64\*64\*0.5B数据,可处理4个分形(一个分形512B),每次迭代中,源操作数中4个连续的16\*64分形将被合并为1个64\*64的方块矩阵,基于方块矩阵做转置,转置后分裂为4个16\*64分形,根据目的操作数分形间隔等参数可以有不同的排布。 |
| 74 | 74 | ||
| 75 | int4b\_t数据类型需要两个数拼成一个int8\_t或uint8\_t的数,拼凑的规则如下: | 75 | int4b\_t数据类型需要两个数拼成一个int8\_t或uint8\_t的数,拼凑的规则如下: |
| 76 | 76 | ||
| 77 | -  | 77 | +  |
| 78 | 78 | ||
| 79 | 如下图所示: | 79 | 如下图所示: |
| 80 | - 共需要处理6144B的数据,每次迭代处理64\*64\*0.5B数据,需要3次迭代可以完成,repeat_time = 3; | 80 | - 共需要处理6144B的数据,每次迭代处理64\*64\*0.5B数据,需要3次迭代可以完成,repeat_time = 3; |
| @@ -82,7 +82,7 @@ | |||
| 82 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); | 82 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); |
| 83 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 | 83 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 |
| 84 | 84 | ||
| 85 | -  | 85 | +  |
| 86 | 86 | ||
| 87 | 如下图示例: | 87 | 如下图示例: |
| 88 | 88 | ||
| @@ -90,7 +90,7 @@ | |||
| 90 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 | 90 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 |
| 91 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 | 91 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 |
| 92 | 92 | ||
| 93 | -  | 93 | +  |
| 94 | 94 | ||
| 95 | 本接口仅在AIC上执行有效。 | 95 | 本接口仅在AIC上执行有效。 |
| 96 | 96 | ||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | 以源操作数搬运场景为例,如下图所示。 | 35 | 以源操作数搬运场景为例,如下图所示。 |
| 36 | 36 | ||
| 37 | - | 37 | + |
| 38 | 38 | ||
| 39 | 本接口仅在AIC上生效。 | 39 | 本接口仅在AIC上生效。 |
| 40 | 40 | ||
| @@ -24,7 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | **图1** 连续数据搬运示意图 | 25 | **图1** 连续数据搬运示意图 |
| 26 | 26 | ||
| 27 | - | 27 | + |
| 28 | 28 | ||
| 29 | ## 高维切分数据搬运 | 29 | ## 高维切分数据搬运 |
| 30 | 30 | ||
| @@ -41,11 +41,11 @@ | |||
| 41 | 41 | ||
| 42 | **图2** 高维切分连续搬运示意图 | 42 | **图2** 高维切分连续搬运示意图 |
| 43 | 43 | ||
| 44 | - | 44 | + |
| 45 | 45 | ||
| 46 | **图3** 高维切分非连续搬运示意图 | 46 | **图3** 高维切分非连续搬运示意图 |
| 47 | 47 | ||
| 48 | - | 48 | + |
| 49 | 49 | ||
| 50 | ## 多维切片数据搬运 | 50 | ## 多维切片数据搬运 |
| 51 | 51 | ||
| @@ -65,7 +65,7 @@ | |||
| 65 | 65 | ||
| 66 | **图4** ND2Nz格式转换示意图 | 66 | **图4** ND2Nz格式转换示意图 |
| 67 | 67 | ||
| 68 | - | 68 | + |
| 69 | 69 | ||
| 70 | ## 随路量化激活搬运 | 70 | ## 随路量化激活搬运 |
| 71 | 71 | ||
| @@ -8,7 +8,7 @@ AI Core采用分层存储架构。计算单元包括Cube、Vector和Scalar;存 | |||
| 8 | 8 | ||
| 9 | **图1** NPU架构版本2201下的AI Core硬件架构 | 9 | **图1** NPU架构版本2201下的AI Core硬件架构 |
| 10 | 10 | ||
| 11 | - | 11 | + |
| 12 | 12 | ||
| 13 | [NPU架构版本3510](../../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)的内部结构如图2所示。与图1相比,数据通路主要有以下变化: | 13 | [NPU架构版本3510](../../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)的内部结构如图2所示。与图1相比,数据通路主要有以下变化: |
| 14 | 14 | ||
| @@ -20,7 +20,7 @@ AI Core采用分层存储架构。计算单元包括Cube、Vector和Scalar;存 | |||
| 20 | 20 | ||
| 21 | **图2** NPU架构版本3510下的AI Core硬件架构与同步关系 | 21 | **图2** NPU架构版本3510下的AI Core硬件架构与同步关系 |
| 22 | 22 | ||
| 23 | - | 23 | + |
| 24 | 24 | ||
| 25 | 本导览后续接口选择均以Ascend 950PR&950DT系列产品(NPU架构版本3510)为准。其他产品的数据通路和接口支持情况应以对应接口文档的产品支持表为准。 | 25 | 本导览后续接口选择均以Ascend 950PR&950DT系列产品(NPU架构版本3510)为准。其他产品的数据通路和接口支持情况应以对应接口文档的产品支持表为准。 |
| 26 | 26 | ||
| @@ -68,7 +68,7 @@ NPU架构版本3510各存储单元的架构基线对齐如下表所示。 | |||
| 68 | 68 | ||
| 69 | **图1** 搬运目的地址重叠 | 69 | **图1** 搬运目的地址重叠 |
| 70 | 70 | ||
| 71 | - | 71 | + |
| 72 | 72 | ||
| 73 | 以下代码展示PIPE_MTE2上两次GM到UB搬运的目的区域重叠时的同步方式: | 73 | 以下代码展示PIPE_MTE2上两次GM到UB搬运的目的区域重叠时的同步方式: |
| 74 | 74 | ||
| @@ -55,7 +55,7 @@ | |||
| 55 | 55 | ||
| 56 | **图1** 掩码寄存器 | 56 | **图1** 掩码寄存器 |
| 57 | 57 | ||
| 58 | - | 58 | + |
| 59 | 59 | ||
| 60 | `b64`操作数的每个元素对应8 bit掩码,且仅最低有效位有效。由于掩码创建接口不支持`b64`模式,需要先通过[asc_create_mask_b32](../../reg_compute/reg_mask/asc_create_mask.md)创建`b32`掩码,再通过[asc_unpack_lower](../../reg_compute/reg_permute_sel/asc_unpack.md)将其展开为`b64`掩码。例如,创建所有`b64`元素均有效的掩码: | 60 | `b64`操作数的每个元素对应8 bit掩码,且仅最低有效位有效。由于掩码创建接口不支持`b64`模式,需要先通过[asc_create_mask_b32](../../reg_compute/reg_mask/asc_create_mask.md)创建`b32`掩码,再通过[asc_unpack_lower](../../reg_compute/reg_permute_sel/asc_unpack.md)将其展开为`b64`掩码。例如,创建所有`b64`元素均有效的掩码: |
| 61 | 61 | ||
| @@ -117,7 +117,7 @@ ND到Nz的格式转换如[图2](#nd2nz_conversion)所示。 | |||
| 117 | 117 | ||
| 118 | **图2** ND2Nz转换示意图<a id="nd2nz_conversion"></a> | 118 | **图2** ND2Nz转换示意图<a id="nd2nz_conversion"></a> |
| 119 | 119 | ||
| 120 | - | 120 | + |
| 121 | 121 | ||
| 122 | ## 返回值说明 | 122 | ## 返回值说明 |
| 123 | 123 | ||
| @@ -100,7 +100,7 @@ ND到Nz的格式转换如[图2](#nd2nz_conversion)所示。 | |||
| 100 | 100 | ||
| 101 | **图2** ND2Nz转换示意图<a id="nd2nz_conversion"></a> | 101 | **图2** ND2Nz转换示意图<a id="nd2nz_conversion"></a> |
| 102 | 102 | ||
| 103 | - | 103 | + |
| 104 | 104 | ||
| 105 | ## 返回值说明 | 105 | ## 返回值说明 |
| 106 | 106 | ||
| @@ -137,13 +137,13 @@ PIPE_MTE1 | |||
| 137 | 137 | ||
| 138 | **图2** feature map格式 | 138 | **图2** feature map格式 |
| 139 | 139 | ||
| 140 | -  | 140 | +  |
| 141 | 141 | ||
| 142 | - 对应的filter的格式如下图: | 142 | - 对应的filter的格式如下图: |
| 143 | 143 | ||
| 144 | **图3** filter的格式 | 144 | **图3** filter的格式 |
| 145 | 145 | ||
| 146 | -  | 146 | +  |
| 147 | 147 | ||
| 148 | 其中n为filter的个数,可以看出维度排布为(Hk,Wk,Ci,n),但是需要注意的是下图的格式还需要根据Mmad中B矩阵的格式转换。 | 148 | 其中n为filter的个数,可以看出维度排布为(Hk,Wk,Ci,n),但是需要注意的是下图的格式还需要根据Mmad中B矩阵的格式转换。 |
| 149 | 149 | ||
| @@ -151,7 +151,7 @@ PIPE_MTE1 | |||
| 151 | 151 | ||
| 152 | 实际操作中,由于存储空间或者计算能力限制,我们通常会将整个卷积计算分块,一次只搬运并计算一小块数据。 | 152 | 实际操作中,由于存储空间或者计算能力限制,我们通常会将整个卷积计算分块,一次只搬运并计算一小块数据。 |
| 153 | 153 | ||
| 154 | - | 154 | + |
| 155 | 155 | ||
| 156 | 对于L0A Buffer中的feature map来说有两种方案,水平分块和垂直分块。分别对应[asc_set_l13d_rpt](../cube_datamove/cube_load_aux_config/asc_set_l13d_rpt.md)参数中rpt_mode的0和1。 | 156 | 对于L0A Buffer中的feature map来说有两种方案,水平分块和垂直分块。分别对应[asc_set_l13d_rpt](../cube_datamove/cube_load_aux_config/asc_set_l13d_rpt.md)参数中rpt_mode的0和1。 |
| 157 | 157 | ||
| @@ -161,13 +161,13 @@ rpt_mode =0时,每次repeat会改变在filter窗口中读取数据点的位置 | |||
| 161 | 161 | ||
| 162 | **图5** rpt_mode = 0时的filter窗口 | 162 | **图5** rpt_mode = 0时的filter窗口 |
| 163 | 163 | ||
| 164 | - | 164 | + |
| 165 | 165 | ||
| 166 | rpt_mode =1的时候filter窗口中读取数据的位置保持不变,每个repeat在feature map中前进C0个元素。 | 166 | rpt_mode =1的时候filter窗口中读取数据的位置保持不变,每个repeat在feature map中前进C0个元素。 |
| 167 | 167 | ||
| 168 | **图6** rpt_mode = 1时的filter窗口 | 168 | **图6** rpt_mode = 1时的filter窗口 |
| 169 | 169 | ||
| 170 | - | 170 | + |
| 171 | 171 | ||
| 172 | ### 使用3D卷积数据搬运完成矩阵计算所需2D格式数据的搬运 | 172 | ### 使用3D卷积数据搬运完成矩阵计算所需2D格式数据的搬运 |
| 173 | 173 | ||
| @@ -118,17 +118,17 @@ PIPE_MTE1 | |||
| 118 | 118 | ||
| 119 | - 对应的feature map格式如下图: | 119 | - 对应的feature map格式如下图: |
| 120 | 120 | ||
| 121 | - | 121 | + |
| 122 | 122 | ||
| 123 | - 对应的filter的格式如下图: | 123 | - 对应的filter的格式如下图: |
| 124 | 124 | ||
| 125 | - | 125 | + |
| 126 | 126 | ||
| 127 | 其中n为filter的个数,可以看出维度排布为(Hk,Wk,Ci,n),但是需要注意的是下图的格式还需要根据Mmad中B矩阵的格式转换。 | 127 | 其中n为filter的个数,可以看出维度排布为(Hk,Wk,Ci,n),但是需要注意的是下图的格式还需要根据Mmad中B矩阵的格式转换。 |
| 128 | 128 | ||
| 129 | 实际操作中,由于存储空间或者计算能力限制,我们通常会将整个卷积计算分块,一次只搬运并计算一小块数据。 | 129 | 实际操作中,由于存储空间或者计算能力限制,我们通常会将整个卷积计算分块,一次只搬运并计算一小块数据。 |
| 130 | 130 | ||
| 131 | - | 131 | + |
| 132 | 132 | ||
| 133 | 对于L0A Buffer中的feature map来说有两种方案,水平分块和垂直分块。分别对应参数中repeatMode的0和1。 | 133 | 对于L0A Buffer中的feature map来说有两种方案,水平分块和垂直分块。分别对应参数中repeatMode的0和1。 |
| 134 | 134 | ||
| @@ -136,11 +136,11 @@ PIPE_MTE1 | |||
| 136 | 136 | ||
| 137 | repeatMode =0时,每次repeat会改变在filter窗口中读取数据点的位置,然后跳到下一个C0的位置。 | 137 | repeatMode =0时,每次repeat会改变在filter窗口中读取数据点的位置,然后跳到下一个C0的位置。 |
| 138 | 138 | ||
| 139 | - | 139 | + |
| 140 | 140 | ||
| 141 | repeatMode =1的时候filter窗口中读取数据的位置保持不变,每个repeat在feature map中前进C0个元素。 | 141 | repeatMode =1的时候filter窗口中读取数据的位置保持不变,每个repeat在feature map中前进C0个元素。 |
| 142 | 142 | ||
| 143 | - | 143 | + |
| 144 | 144 | ||
| 145 | ## 调用示例 | 145 | ## 调用示例 |
| 146 | 146 | ||
| @@ -43,7 +43,7 @@ | |||
| 43 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); | 43 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); |
| 44 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 | 44 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 |
| 45 | 45 | ||
| 46 | - | 46 | + |
| 47 | 47 | ||
| 48 | 如下图示例: | 48 | 如下图示例: |
| 49 | 49 | ||
| @@ -51,7 +51,7 @@ | |||
| 51 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 | 51 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 |
| 52 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 | 52 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 |
| 53 | 53 | ||
| 54 | - | 54 | + |
| 55 | 55 | ||
| 56 | - 对于half/bfloat16_t数据类型,每次迭代处理16 × 16 × 2B数据,可处理1个分形(一个分形512B),每次迭代中,源操作数中1个16 × 16分形将被转置。 | 56 | - 对于half/bfloat16_t数据类型,每次迭代处理16 × 16 × 2B数据,可处理1个分形(一个分形512B),每次迭代中,源操作数中1个16 × 16分形将被转置。 |
| 57 | - 因为每次迭代处理16 × 16 × 2B数据,需要3次迭代可以完成,repeat_time = 3; | 57 | - 因为每次迭代处理16 × 16 × 2B数据,需要3次迭代可以完成,repeat_time = 3; |
| @@ -59,7 +59,7 @@ | |||
| 59 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址无间隔; | 59 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址无间隔; |
| 60 | - 该场景下,因为其分形即为方块矩阵,每个迭代处理一个分形,不存在迭代内分形的间隔,该参数设置无效。 | 60 | - 该场景下,因为其分形即为方块矩阵,每个迭代处理一个分形,不存在迭代内分形的间隔,该参数设置无效。 |
| 61 | 61 | ||
| 62 | - | 62 | + |
| 63 | 63 | ||
| 64 | - 对于float/int32_t/uint32_t数据类型,每次迭代处理16 × 16 × 4B数据,可处理2个分形(一个分形512B),每次迭代中,源操作数2个连续的16 × 8分形将被合并为1个16 × 16的方块矩阵,基于方块矩阵做转置,转置后分裂为2个16 × 8分形,根据目的操作数分形间隔等参数可以有不同的排布。 | 64 | - 对于float/int32_t/uint32_t数据类型,每次迭代处理16 × 16 × 4B数据,可处理2个分形(一个分形512B),每次迭代中,源操作数2个连续的16 × 8分形将被合并为1个16 × 16的方块矩阵,基于方块矩阵做转置,转置后分裂为2个16 × 8分形,根据目的操作数分形间隔等参数可以有不同的排布。 |
| 65 | 如下图示例: | 65 | 如下图示例: |
| @@ -68,14 +68,14 @@ | |||
| 68 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); | 68 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); |
| 69 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为0(单位:512B)。 | 69 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为0(单位:512B)。 |
| 70 | 70 | ||
| 71 | - | 71 | + |
| 72 | 72 | ||
| 73 | 如下图示例: | 73 | 如下图示例: |
| 74 | - repeat_time和src_stride的解释和上图示例一致。 | 74 | - repeat_time和src_stride的解释和上图示例一致。 |
| 75 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 | 75 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 |
| 76 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为2(单位:512B)。 | 76 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为2(单位:512B)。 |
| 77 | 77 | ||
| 78 | - | 78 | + |
| 79 | 79 | ||
| 80 | ## 函数原型 | 80 | ## 函数原型 |
| 81 | 81 | ||
| @@ -115,17 +115,17 @@ PIPE_MTE1 | |||
| 115 | 115 | ||
| 116 | - 对应的feature map格式如下图: | 116 | - 对应的feature map格式如下图: |
| 117 | 117 | ||
| 118 | - | 118 | + |
| 119 | 119 | ||
| 120 | - 对应的filter的格式如下图: | 120 | - 对应的filter的格式如下图: |
| 121 | 121 | ||
| 122 | - | 122 | + |
| 123 | 123 | ||
| 124 | 其中n为filter的个数,可以看出维度排布为(Hk,Wk,Ci,n),但是需要注意的是下图的格式还需要根据Mmad中B矩阵的格式转换。 | 124 | 其中n为filter的个数,可以看出维度排布为(Hk,Wk,Ci,n),但是需要注意的是下图的格式还需要根据Mmad中B矩阵的格式转换。 |
| 125 | 125 | ||
| 126 | 实际操作中,由于存储空间或者计算能力限制,我们通常会将整个卷积计算分块,一次只搬运并计算一小块数据。 | 126 | 实际操作中,由于存储空间或者计算能力限制,我们通常会将整个卷积计算分块,一次只搬运并计算一小块数据。 |
| 127 | 127 | ||
| 128 | - | 128 | + |
| 129 | 129 | ||
| 130 | 对于L0B Buffer中的feature map来说有两种方案,水平分块和垂直分块。分别对应参数中repeatMode的0和1。 | 130 | 对于L0B Buffer中的feature map来说有两种方案,水平分块和垂直分块。分别对应参数中repeatMode的0和1。 |
| 131 | 131 | ||
| @@ -133,11 +133,11 @@ PIPE_MTE1 | |||
| 133 | 133 | ||
| 134 | repeatMode =0时,每次repeat会改变在filter窗口中读取数据点的位置,然后跳到下一个C0的位置。 | 134 | repeatMode =0时,每次repeat会改变在filter窗口中读取数据点的位置,然后跳到下一个C0的位置。 |
| 135 | 135 | ||
| 136 | - | 136 | + |
| 137 | 137 | ||
| 138 | repeatMode =1的时候filter窗口中读取数据的位置保持不变,每个repeat在feature map中前进C0个元素。 | 138 | repeatMode =1的时候filter窗口中读取数据的位置保持不变,每个repeat在feature map中前进C0个元素。 |
| 139 | 139 | ||
| 140 | - | 140 | + |
| 141 | 141 | ||
| 142 | ## 调用示例 | 142 | ## 调用示例 |
| 143 | 143 | ||
| @@ -43,7 +43,7 @@ | |||
| 43 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); | 43 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); |
| 44 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 | 44 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 |
| 45 | 45 | ||
| 46 | - | 46 | + |
| 47 | 47 | ||
| 48 | 如下图示例: | 48 | 如下图示例: |
| 49 | 49 | ||
| @@ -51,7 +51,7 @@ | |||
| 51 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 | 51 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 |
| 52 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 | 52 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 |
| 53 | 53 | ||
| 54 | - | 54 | + |
| 55 | 55 | ||
| 56 | - 对于half/bfloat16_t数据类型,每次迭代处理16 × 16 × 2B数据,可处理1个分形(一个分形512B),每次迭代中,源操作数中1个16 × 16分形将被转置。 | 56 | - 对于half/bfloat16_t数据类型,每次迭代处理16 × 16 × 2B数据,可处理1个分形(一个分形512B),每次迭代中,源操作数中1个16 × 16分形将被转置。 |
| 57 | - 因为每次迭代处理16 × 16 × 2B数据,需要3次迭代可以完成,repeat_time = 3; | 57 | - 因为每次迭代处理16 × 16 × 2B数据,需要3次迭代可以完成,repeat_time = 3; |
| @@ -59,7 +59,7 @@ | |||
| 59 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址无间隔; | 59 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址无间隔; |
| 60 | - 该场景下,因为其分形即为方块矩阵,每个迭代处理一个分形,不存在迭代内分形的间隔,该参数设置无效。 | 60 | - 该场景下,因为其分形即为方块矩阵,每个迭代处理一个分形,不存在迭代内分形的间隔,该参数设置无效。 |
| 61 | 61 | ||
| 62 | - | 62 | + |
| 63 | 63 | ||
| 64 | - 对于float/int32_t/uint32_t数据类型,每次迭代处理16 × 16 × 4B数据,可处理2个分形(一个分形512B),每次迭代中,源操作数2个连续的16 × 8分形将被合并为1个16 × 16的方块矩阵,基于方块矩阵做转置,转置后分裂为2个16 × 8分形,根据目的操作数分形间隔等参数可以有不同的排布。 | 64 | - 对于float/int32_t/uint32_t数据类型,每次迭代处理16 × 16 × 4B数据,可处理2个分形(一个分形512B),每次迭代中,源操作数2个连续的16 × 8分形将被合并为1个16 × 16的方块矩阵,基于方块矩阵做转置,转置后分裂为2个16 × 8分形,根据目的操作数分形间隔等参数可以有不同的排布。 |
| 65 | 如下图示例: | 65 | 如下图示例: |
| @@ -68,14 +68,14 @@ | |||
| 68 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); | 68 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); |
| 69 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为0(单位:512B)。 | 69 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为0(单位:512B)。 |
| 70 | 70 | ||
| 71 | - | 71 | + |
| 72 | 72 | ||
| 73 | 如下图示例: | 73 | 如下图示例: |
| 74 | - repeat_time和src_stride的解释和上图示例一致。 | 74 | - repeat_time和src_stride的解释和上图示例一致。 |
| 75 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 | 75 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 |
| 76 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为2(单位:512B)。 | 76 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为2(单位:512B)。 |
| 77 | 77 | ||
| 78 | - | 78 | + |
| 79 | 79 | ||
| 80 | ## 函数原型 | 80 | ## 函数原型 |
| 81 | 81 | ||
| @@ -42,21 +42,21 @@ | |||
| 42 | - src_stride = 1,表示相邻迭代间,源操作数前一个方块矩阵与后一个方块矩阵起始地址的间隔为1(单位:32 × 32 × 1B),这里的单位实际上是拼接后的方块矩阵的大小; | 42 | - src_stride = 1,表示相邻迭代间,源操作数前一个方块矩阵与后一个方块矩阵起始地址的间隔为1(单位:32 × 32 × 1B),这里的单位实际上是拼接后的方块矩阵的大小; |
| 43 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); | 43 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); |
| 44 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 | 44 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 |
| 45 | - | 45 | + |
| 46 | 46 | ||
| 47 | 如下图示例: | 47 | 如下图示例: |
| 48 | 48 | ||
| 49 | - repeat_time和src_stride的解释和上图示例一致。 | 49 | - repeat_time和src_stride的解释和上图示例一致。 |
| 50 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 | 50 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 |
| 51 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 | 51 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 |
| 52 | - | 52 | + |
| 53 | 53 | ||
| 54 | - 对于half/bfloat16_t数据类型,每次迭代处理16 × 16 × 2B数据,可处理1个分形(一个分形512B),每次迭代中,源操作数中1个16 × 16分形将被转置。 | 54 | - 对于half/bfloat16_t数据类型,每次迭代处理16 × 16 × 2B数据,可处理1个分形(一个分形512B),每次迭代中,源操作数中1个16 × 16分形将被转置。 |
| 55 | - 因为每次迭代处理16 × 16 × 2B数据,需要3次迭代可以完成,repeat_time = 3; | 55 | - 因为每次迭代处理16 × 16 × 2B数据,需要3次迭代可以完成,repeat_time = 3; |
| 56 | - src_stride = 1,表示相邻迭代间,源操作数前一个方块矩阵与后一个方块矩阵起始地址的间隔为1 (单位:16 × 16 × 2B); | 56 | - src_stride = 1,表示相邻迭代间,源操作数前一个方块矩阵与后一个方块矩阵起始地址的间隔为1 (单位:16 × 16 × 2B); |
| 57 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址无间隔; | 57 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址无间隔; |
| 58 | - 该场景下,因为其分形即为方块矩阵,每个迭代处理一个分形,不存在迭代内分形的间隔,该参数设置无效。 | 58 | - 该场景下,因为其分形即为方块矩阵,每个迭代处理一个分形,不存在迭代内分形的间隔,该参数设置无效。 |
| 59 | - | 59 | + |
| 60 | 60 | ||
| 61 | - 对于float/int32_t/uint32_t数据类型,每次迭代处理16 × 16 × 4B数据,可处理2个分形(一个分形512B),每次迭代中,源操作数2个连续的16 × 8分形将被合并为1个16 × 16的方块矩阵,基于方块矩阵做转置,转置后分裂为2个16 × 8分形,根据目的操作数分形间隔等参数可以有不同的排布。 | 61 | - 对于float/int32_t/uint32_t数据类型,每次迭代处理16 × 16 × 4B数据,可处理2个分形(一个分形512B),每次迭代中,源操作数2个连续的16 × 8分形将被合并为1个16 × 16的方块矩阵,基于方块矩阵做转置,转置后分裂为2个16 × 8分形,根据目的操作数分形间隔等参数可以有不同的排布。 |
| 62 | 如下图示例: | 62 | 如下图示例: |
| @@ -64,19 +64,19 @@ | |||
| 64 | - src_stride = 1,表示相邻迭代间,源操作数前一个方块矩阵与后一个方块矩阵起始地址的间隔为1(单位:16 × 16 × 4B),这里的单位实际上是拼接后的方块矩阵的大小; | 64 | - src_stride = 1,表示相邻迭代间,源操作数前一个方块矩阵与后一个方块矩阵起始地址的间隔为1(单位:16 × 16 × 4B),这里的单位实际上是拼接后的方块矩阵的大小; |
| 65 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); | 65 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); |
| 66 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为0(单位:512B)。 | 66 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为0(单位:512B)。 |
| 67 | - | 67 | + |
| 68 | 68 | ||
| 69 | 如下图示例: | 69 | 如下图示例: |
| 70 | - repeat_time和src_stride的解释和上图示例一致。 | 70 | - repeat_time和src_stride的解释和上图示例一致。 |
| 71 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 | 71 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 |
| 72 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为2(单位:512B)。 | 72 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形结束地址与后一个分形起始地址的间隔为2(单位:512B)。 |
| 73 | - | 73 | + |
| 74 | 74 | ||
| 75 | - 对于int4b\_t数据类型,每次迭代处理64\*64\*0.5B数据,可处理4个分形(一个分形512B),每次迭代中,源操作数中4个连续的16\*64分形将被合并为1个64\*64的方块矩阵,基于方块矩阵做转置,转置后分裂为4个16\*64分形,根据目的操作数分形间隔等参数可以有不同的排布。 | 75 | - 对于int4b\_t数据类型,每次迭代处理64\*64\*0.5B数据,可处理4个分形(一个分形512B),每次迭代中,源操作数中4个连续的16\*64分形将被合并为1个64\*64的方块矩阵,基于方块矩阵做转置,转置后分裂为4个16\*64分形,根据目的操作数分形间隔等参数可以有不同的排布。 |
| 76 | 76 | ||
| 77 | int4b\_t数据类型需要两个数拼成一个int8\_t或uint8\_t的数,拼凑的规则如下: | 77 | int4b\_t数据类型需要两个数拼成一个int8\_t或uint8\_t的数,拼凑的规则如下: |
| 78 | 78 | ||
| 79 | -  | 79 | +  |
| 80 | 80 | ||
| 81 | 如下图所示: | 81 | 如下图所示: |
| 82 | - 共需要处理6144B的数据,每次迭代处理64\*64\*0.5B数据,需要3次迭代可以完成,repeat_time = 3; | 82 | - 共需要处理6144B的数据,每次迭代处理64\*64\*0.5B数据,需要3次迭代可以完成,repeat_time = 3; |
| @@ -84,7 +84,7 @@ | |||
| 84 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); | 84 | - dst_gap = 1,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址到下一个迭代第一个分形起始地址的间隔为1(单位:512B); |
| 85 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 | 85 | - dst_frac_gap = 0,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为0(单位:512B)。 |
| 86 | 86 | ||
| 87 | -  | 87 | +  |
| 88 | 88 | ||
| 89 | 如下图示例: | 89 | 如下图示例: |
| 90 | 90 | ||
| @@ -92,7 +92,7 @@ | |||
| 92 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 | 92 | - dst_gap = 0,表示相邻迭代间,目的操作数前一个迭代第一个分形的结束地址和下一个迭代第一个分形起始地址无间隔。 |
| 93 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 | 93 | - dst_frac_gap = 2,表示每个迭代内目的操作数前一个分形的结束地址与后一个分形起始地址的间隔为2(单位:512B)。 |
| 94 | 94 | ||
| 95 | -  | 95 | +  |
| 96 | 96 | ||
| 97 | ## 函数原型 | 97 | ## 函数原型 |
| 98 | 98 | ||
| @@ -36,7 +36,7 @@ | |||
| 36 | - asc_deq_int162b8_l:将数据存放在每个DataBlock的低半块。 | 36 | - asc_deq_int162b8_l:将数据存放在每个DataBlock的低半块。 |
| 37 | 37 | ||
| 38 | 如下图所示: | 38 | 如下图所示: |
| 39 | - | 39 | + |
| 40 | 40 | ||
| 41 | 计算公式如下: | 41 | 计算公式如下: |
| 42 | 42 | ||
| @@ -35,11 +35,11 @@ | |||
| 35 | asc_mrgsort4处理的数据一般是经过asc_bitsort指令处理后的数据,也就是asc_bitsort指令的输出,队列的结构Region Proposal如下所示: | 35 | asc_mrgsort4处理的数据一般是经过asc_bitsort指令处理后的数据,也就是asc_bitsort指令的输出,队列的结构Region Proposal如下所示: |
| 36 | - 数据类型为float,每个结构占据8 Bytes。 | 36 | - 数据类型为float,每个结构占据8 Bytes。 |
| 37 | 37 | ||
| 38 | - | 38 | + |
| 39 | 39 | ||
| 40 | - 数据类型为half,每个结构也占据8 Bytes,中间有2 Bytes保留。 | 40 | - 数据类型为half,每个结构也占据8 Bytes,中间有2 Bytes保留。 |
| 41 | 41 | ||
| 42 | - | 42 | + |
| 43 | 43 | ||
| 44 | ## 函数原型 | 44 | ## 函数原型 |
| 45 | 45 | ||
| @@ -49,19 +49,19 @@ | |||
| 49 | 以下以2维的例子,介绍几个典型使用场景。 | 49 | 以下以2维的例子,介绍几个典型使用场景。 |
| 50 | 50 | ||
| 51 | - 2D Padding场景,使用固定值填充方式 | 51 | - 2D Padding场景,使用固定值填充方式 |
| 52 | - | 52 | + |
| 53 | 53 | ||
| 54 | - 2D Padding场景,使用最近值填充方式 | 54 | - 2D Padding场景,使用最近值填充方式 |
| 55 | - | 55 | + |
| 56 | 56 | ||
| 57 | - 2D Transpose场景 | 57 | - 2D Transpose场景 |
| 58 | - | 58 | + |
| 59 | 59 | ||
| 60 | - 2D Slice场景 | 60 | - 2D Slice场景 |
| 61 | - | 61 | + |
| 62 | 62 | ||
| 63 | - 2D Broadcast场景 | 63 | - 2D Broadcast场景 |
| 64 | - | 64 | + |
| 65 | 65 | ||
| 66 | ## 函数原型 | 66 | ## 函数原型 |
| 67 | 67 | ||
| @@ -118,7 +118,7 @@ PIPE_MTE2 | |||
| 118 | ## 调用示例 | 118 | ## 调用示例 |
| 119 | 119 | ||
| 120 | 2D Padding场景,使用固定值填充方式 | 120 | 2D Padding场景,使用固定值填充方式 |
| 121 | - | 121 | + |
| 122 | 122 | ||
| 123 | ```cpp | 123 | ```cpp |
| 124 | // total_length指参与搬运的数据总长度。src是外部输入的half类型的GM内存。 | 124 | // total_length指参与搬运的数据总长度。src是外部输入的half类型的GM内存。 |
| @@ -32,7 +32,7 @@ | |||
| 32 | 32 | ||
| 33 | 该指令会根据索引值index将源操作数src中的元素分散到目的操作数dst中。分散过程如下图所示: | 33 | 该指令会根据索引值index将源操作数src中的元素分散到目的操作数dst中。分散过程如下图所示: |
| 34 | 34 | ||
| 35 | - | 35 | + |
| 36 | 36 | ||
| 37 | ## 函数原型 | 37 | ## 函数原型 |
| 38 | 38 | ||
| @@ -34,15 +34,15 @@ | |||
| 34 | 34 | ||
| 35 | 单次repeat内转换规则如下: | 35 | 单次repeat内转换规则如下: |
| 36 | 36 | ||
| 37 | -- 当输入数据类型位宽为16位时,每个DataBlock中包含16个数,指令内部会循环16次,每次循环都会分别从指定的16个DataBlock中的对应位置取值,组成一个新的DataBlock单元放入目的地址中。如下图所示,图中的srcList[0]-srcList[15]代表源操作数的16个DataBlock。 | 37 | +- 当输入数据类型位宽为16位时,每个DataBlock中包含16个数,指令内部会循环16次,每次循环都会分别从指定的16个DataBlock中的对应位置取值,组成一个新的DataBlock单元放入目的地址中。如下图所示,图中的srcList[0]-srcList[15]代表源操作数的16个DataBlock。 |
| 38 | 38 | ||
| 39 | -- 当数据类型位宽为32位时,每个DataBlock包含8个数,指令内部会循环8次,每次循环都会分别从指定的16个DataBlock中的对应位置取值,组成2个新的DataBlock放入目的地址中。如下图所示: | 39 | +- 当数据类型位宽为32位时,每个DataBlock包含8个数,指令内部会循环8次,每次循环都会分别从指定的16个DataBlock中的对应位置取值,组成2个新的DataBlock放入目的地址中。如下图所示: |
| 40 | 40 | ||
| 41 | -- 当数据类型位宽为8位时,每个DataBlock包含32个数,指令内部会循环16次,每次循环都会分别从指定的16个DataBlock中的对应位置取值,组成半个DataBlock放入目的地址中,读取和存放是在DataBlock的高半部还是低半部由参数srcHighHalf和dstHighHalf决定。如下图所示: | 41 | +- 当数据类型位宽为8位时,每个DataBlock包含32个数,指令内部会循环16次,每次循环都会分别从指定的16个DataBlock中的对应位置取值,组成半个DataBlock放入目的地址中,读取和存放是在DataBlock的高半部还是低半部由参数srcHighHalf和dstHighHalf决定。如下图所示: |
| 42 | 42 | ||
| 43 | 基于以上的转换规则,使用该接口进行NC1HWC0格式转换或者矩阵转置。NC1HWC0格式转换相对复杂,这里给出其具体的转换方法: | 43 | 基于以上的转换规则,使用该接口进行NC1HWC0格式转换或者矩阵转置。NC1HWC0格式转换相对复杂,这里给出其具体的转换方法: |
| 44 | 44 | ||
| 45 | -NCHW格式转换成NC1HWC0格式时,如果是数据类型的位宽为32位或者16位,则C0=16;如果数据类型的位宽为8位,则C0=32。下图以C0=16为例进行介绍: | 45 | +NCHW格式转换成NC1HWC0格式时,如果是数据类型的位宽为32位或者16位,则C0=16;如果数据类型的位宽为8位,则C0=32。下图以C0=16为例进行介绍: |
| 46 | 46 | ||
| 47 | ## 函数原型 | 47 | ## 函数原型 |
| 48 | 48 | ||
| @@ -39,7 +39,7 @@ | |||
| 39 | 39 | ||
| 40 | **图1** 解交织实现流程 | 40 | **图1** 解交织实现流程 |
| 41 | 41 | ||
| 42 | - | 42 | + |
| 43 | 43 | ||
| 44 | 本接口为Reg矢量计算接口,仅在AIV上生效。 | 44 | 本接口为Reg矢量计算接口,仅在AIV上生效。 |
| 45 | 45 | ||
| @@ -37,7 +37,7 @@ | |||
| 37 | 37 | ||
| 38 | **图 1** int8_t类型交织过程 | 38 | **图 1** int8_t类型交织过程 |
| 39 | 39 | ||
| 40 | - | 40 | + |
| 41 | 41 | ||
| 42 | 本接口为Reg矢量计算接口,仅在AIV上生效。 | 42 | 本接口为Reg矢量计算接口,仅在AIV上生效。 |
| 43 | 43 | ||
| @@ -44,7 +44,7 @@ $$ | |||
| 44 | 44 | ||
| 45 | **图 1** asc_mull计算示意图 | 45 | **图 1** asc_mull计算示意图 |
| 46 | 46 | ||
| 47 | - | 47 | + |
| 48 | 48 | ||
| 49 | 本接口为Reg矢量计算接口,仅在AIV上生效。 | 49 | 本接口为Reg矢量计算接口,仅在AIV上生效。 |
| 50 | 50 | ||
| @@ -1,3 +0,0 @@ | |||
| 1 | -version https://git-lfs.github.com/spec/v1 | ||
| 2 | -oid sha256:4824801cea2378fa6bfdedbe09347be7fd2a644069b6eda9d6f81ff0cf819954 | ||
| 3 | -size 80729 | ||
| @@ -1,3 +0,0 @@ | |||
| 1 | -version https://git-lfs.github.com/spec/v1 | ||
| 2 | -oid sha256:3db2eb0af36f2fb07f6d84cb5a398cd45e4a689307ec186178cabdca0fc99425 | ||
| 3 | -size 34026 | ||
| @@ -1,3 +0,0 @@ | |||
| 1 | -version https://git-lfs.github.com/spec/v1 | ||
| 2 | -oid sha256:4d5f083ea5c57b6ba371ae45ec0a7d8e9383fbd3abe100125ba81dc243757317 | ||
| 3 | -size 33215 | ||
| @@ -1,3 +0,0 @@ | |||
| 1 | -version https://git-lfs.github.com/spec/v1 | ||
| 2 | -oid sha256:4c526868ef8f0ec93cf1a423849186181140526f2b51ffc90a230adceb272dc2 | ||
| 3 | -size 349632 | ||
| @@ -46,7 +46,7 @@ AI Core内外包含多级存储单元,各存储单元的主要用途如下: | |||
| 46 | 46 | ||
| 47 | **图1** 地址重叠示例(不支持) | 47 | **图1** 地址重叠示例(不支持) |
| 48 | 48 | ||
| 49 | - | 49 | + |
| 50 | 50 | ||
| 51 | > [!NOTE]说明 | 51 | > [!NOTE]说明 |
| 52 | >本节所述地址重叠通用约束适用于一般情况,API参考中如有额外特殊说明的,则以具体API中的说明为准。 | 52 | >本节所述地址重叠通用约束适用于一般情况,API参考中如有额外特殊说明的,则以具体API中的说明为准。 |
| @@ -65,33 +65,33 @@ AI Core内外包含多级存储单元,各存储单元的主要用途如下: | |||
| 65 | 65 | ||
| 66 | **图2** 单次迭代内的8个DataBlock进行Exp计算示意图 | 66 | **图2** 单次迭代内的8个DataBlock进行Exp计算示意图 |
| 67 | 67 | ||
| 68 | - | 68 | + |
| 69 | 69 | ||
| 70 | - 矢量计算API支持开发者通过repeatTime来配置迭代次数,从而控制指令的多次迭代执行。假设repeatTime设置为2,矢量计算单元会进行2个迭代的计算,可计算出2 * 8(每个迭代8个DataBlock)* 32Byte(每个DataBlock 32Byte) = 512Byte的结果。如果数据类型为half,则计算了256个元素。下图展示了2次迭代Exp计算的示意图。由于硬件限制,repeatTime不能超过255。 | 70 | - 矢量计算API支持开发者通过repeatTime来配置迭代次数,从而控制指令的多次迭代执行。假设repeatTime设置为2,矢量计算单元会进行2个迭代的计算,可计算出2 * 8(每个迭代8个DataBlock)* 32Byte(每个DataBlock 32Byte) = 512Byte的结果。如果数据类型为half,则计算了256个元素。下图展示了2次迭代Exp计算的示意图。由于硬件限制,repeatTime不能超过255。 |
| 71 | 71 | ||
| 72 | **图3** 2次迭代Exp计算 | 72 | **图3** 2次迭代Exp计算 |
| 73 | 73 | ||
| 74 | -  | 74 | +  |
| 75 | 75 | ||
| 76 | - 针对同一个迭代中的数据,可以通过mask参数进行掩码操作来控制实际参与计算的个数。下图为进行Abs计算时通过mask逐比特模式按位控制哪些元素参与计算的示意图,1表示参与计算,0表示不参与计算。 | 76 | - 针对同一个迭代中的数据,可以通过mask参数进行掩码操作来控制实际参与计算的个数。下图为进行Abs计算时通过mask逐比特模式按位控制哪些元素参与计算的示意图,1表示参与计算,0表示不参与计算。 |
| 77 | 77 | ||
| 78 | **图4** 通过mask参数进行掩码操作示意图(以float数据类型为例) | 78 | **图4** 通过mask参数进行掩码操作示意图(以float数据类型为例) |
| 79 | 79 | ||
| 80 | -  | 80 | +  |
| 81 | 81 | ||
| 82 | - 矢量计算单元还支持带间隔的向量计算,通过dataBlockStride(单次迭代内不同DataBlock间地址步长)和repeatStride(相邻迭代间相同DataBlock的地址步长)来进行配置。 | 82 | - 矢量计算单元还支持带间隔的向量计算,通过dataBlockStride(单次迭代内不同DataBlock间地址步长)和repeatStride(相邻迭代间相同DataBlock的地址步长)来进行配置。 |
| 83 | - dataBlockStride <br/> | 83 | - dataBlockStride <br/> |
| 84 | 如果需要控制单次迭代内,数据处理的步长,可以通过设置同一迭代内不同DataBlock的地址步长dataBlockStride来实现。下图给出了单次迭代内非连续场景的示意图,示例中源操作数的dataBlockStride配置为2,表示单次迭代内不同DataBlock间地址步长(起始地址之间的间隔)为2个DataBlock。<br/> | 84 | 如果需要控制单次迭代内,数据处理的步长,可以通过设置同一迭代内不同DataBlock的地址步长dataBlockStride来实现。下图给出了单次迭代内非连续场景的示意图,示例中源操作数的dataBlockStride配置为2,表示单次迭代内不同DataBlock间地址步长(起始地址之间的间隔)为2个DataBlock。<br/> |
| 85 | **图5** 单次迭代内非连续场景的示意图 | 85 | **图5** 单次迭代内非连续场景的示意图 |
| 86 | 86 | ||
| 87 | -  | 87 | +  |
| 88 | 88 | ||
| 89 | - repeatStride | 89 | - repeatStride |
| 90 | 当repeatTime大于1,需要多次迭代完成矢量计算时,您可以根据不同的使用场景合理设置相邻迭代间相同DataBlock的地址步长repeatStride的值。<br/> | 90 | 当repeatTime大于1,需要多次迭代完成矢量计算时,您可以根据不同的使用场景合理设置相邻迭代间相同DataBlock的地址步长repeatStride的值。<br/> |
| 91 | 下图给出了多次迭代间非连续场景的示意图,示例中源操作数和目的操作数的repeatStride均配置为9,表示相邻迭代间相同DataBlock起始地址之间的间隔为9个DataBlock。相同DataBlock是指DataBlock在迭代内的位置相同,比如下图中的src1和src9处于相邻迭代,在迭代内都是第一个DataBlock的位置,其间隔即为repeatStride的数值。 <br/> | 91 | 下图给出了多次迭代间非连续场景的示意图,示例中源操作数和目的操作数的repeatStride均配置为9,表示相邻迭代间相同DataBlock起始地址之间的间隔为9个DataBlock。相同DataBlock是指DataBlock在迭代内的位置相同,比如下图中的src1和src9处于相邻迭代,在迭代内都是第一个DataBlock的位置,其间隔即为repeatStride的数值。 <br/> |
| 92 | **图6** 多次迭代间非连续场景的示意图 | 92 | **图6** 多次迭代间非连续场景的示意图 |
| 93 | 93 | ||
| 94 | -  | 94 | +  |
| 95 | 95 | ||
| 96 | 下文中给出了dataBlockStride、repeatStride、mask的详细配置说明和示例。 | 96 | 下文中给出了dataBlockStride、repeatStride、mask的详细配置说明和示例。 |
| 97 | 97 | ||
| @@ -103,7 +103,7 @@ dataBlockStride是指同一迭代内不同DataBlock的地址步长。 | |||
| 103 | 103 | ||
| 104 | **图7** dataBlockStride不同取值举例 | 104 | **图7** dataBlockStride不同取值举例 |
| 105 | 105 | ||
| 106 | - | 106 | + |
| 107 | 107 | ||
| 108 | ### repeatStride<a name="repeatStride"></a> | 108 | ### repeatStride<a name="repeatStride"></a> |
| 109 | 109 | ||
| @@ -111,19 +111,19 @@ repeatStride是指相邻迭代间相同DataBlock的地址步长。 | |||
| 111 | 111 | ||
| 112 | - **连续计算场景:** 假设定义一个Tensor供目的操作数和源操作数同时使用(即地址重叠),repeatStride取值为8。此时,矢量计算单元第一次迭代读取连续8个DataBlock,第二轮迭代读取下一个连续的8个DataBlock,通过多次迭代即可完成所有输入数据的计算。 | 112 | - **连续计算场景:** 假设定义一个Tensor供目的操作数和源操作数同时使用(即地址重叠),repeatStride取值为8。此时,矢量计算单元第一次迭代读取连续8个DataBlock,第二轮迭代读取下一个连续的8个DataBlock,通过多次迭代即可完成所有输入数据的计算。 |
| 113 | 113 | ||
| 114 | -  | 114 | +  |
| 115 | 115 | ||
| 116 | - **非连续计算场景:** repeatStride取值大于8(如取10)时,则相邻迭代间矢量计算单元读取的数据在地址上不连续,出现2个DataBlock的间隔。 | 116 | - **非连续计算场景:** repeatStride取值大于8(如取10)时,则相邻迭代间矢量计算单元读取的数据在地址上不连续,出现2个DataBlock的间隔。 |
| 117 | 117 | ||
| 118 | -  | 118 | +  |
| 119 | 119 | ||
| 120 | - **反复计算场景:** repeatStride取值为0时,矢量计算单元会对首个连续的8个DataBlock进行反复读取和计算。 | 120 | - **反复计算场景:** repeatStride取值为0时,矢量计算单元会对首个连续的8个DataBlock进行反复读取和计算。 |
| 121 | 121 | ||
| 122 | -  | 122 | +  |
| 123 | 123 | ||
| 124 | - **部分重复计算:** repeatStride取值大于0且小于8时,相邻迭代间部分数据会被矢量计算单元重复读取和计算,此种情形一般场景不涉及。 | 124 | - **部分重复计算:** repeatStride取值大于0且小于8时,相邻迭代间部分数据会被矢量计算单元重复读取和计算,此种情形一般场景不涉及。 |
| 125 | 125 | ||
| 126 | -  | 126 | +  |
| 127 | 127 | ||
| 128 | ## 掩码操作 | 128 | ## 掩码操作 |
| 129 | 129 | ||
| @@ -161,7 +161,7 @@ asc_add(dstLocal, src0Local, src1Local, repeatTime, dst_block_stride, src0_block | |||
| 161 | 161 | ||
| 162 | mask过程如下:<br/> | 162 | mask过程如下:<br/> |
| 163 | mask={6148914691236517205, 6148914691236517205}(注:6148914691236517205表示64位二进制数0b010101....01,mask按照低位到高位的顺序排布) | 163 | mask={6148914691236517205, 6148914691236517205}(注:6148914691236517205表示64位二进制数0b010101....01,mask按照低位到高位的顺序排布) |
| 164 | - | 164 | + |
| 165 | 165 | ||
| 166 | ```cpp | 166 | ```cpp |
| 167 | // 数据类型为int32_t | 167 | // 数据类型为int32_t |
| @@ -188,7 +188,7 @@ asc_add(dstLocal, src0Local, src1Local, repeatTime, dst_block_stride, src0_block | |||
| 188 | 188 | ||
| 189 | mask过程如下:<br/> | 189 | mask过程如下:<br/> |
| 190 | mask={6148914691236517205, 0}(注:6148914691236517205表示64位二进制数0b010101....01) | 190 | mask={6148914691236517205, 0}(注:6148914691236517205表示64位二进制数0b010101....01) |
| 191 | - | 191 | + |
| 192 | 192 | ||
| 193 | ## 以数组方式申请内存<a name="以数组方式申请内存"></a> | 193 | ## 以数组方式申请内存<a name="以数组方式申请内存"></a> |
| 194 | 194 | ||
| @@ -64,7 +64,7 @@ Reg向量计算C API提供了下表所示多种搬运指令,合理选择搬运 | |||
| 64 | 64 | ||
| 65 | **图1** half转int32_t类型转换过程<a id="fig1"></a> | 65 | **图1** half转int32_t类型转换过程<a id="fig1"></a> |
| 66 | 66 | ||
| 67 | -  | 67 | +  |
| 68 | 68 | ||
| 69 | ```cpp | 69 | ```cpp |
| 70 | __simd_vf__ inline void half_to_int32_vf(__ubuf__ int32_t* y_addr, __ubuf__ half* x_addr) | 70 | __simd_vf__ inline void half_to_int32_vf(__ubuf__ int32_t* y_addr, __ubuf__ half* x_addr) |
| @@ -86,7 +86,7 @@ Reg向量计算C API提供了下表所示多种搬运指令,合理选择搬运 | |||
| 86 | 86 | ||
| 87 | **图2** float转int16_t类型转换过程<a id="fig2"></a> | 87 | **图2** float转int16_t类型转换过程<a id="fig2"></a> |
| 88 | 88 | ||
| 89 | -  | 89 | +  |
| 90 | 90 | ||
| 91 | ```cpp | 91 | ```cpp |
| 92 | __simd_vf__ inline void float_to_int16_vf(__ubuf__ int16_t* y_addr, __ubuf__ float* x_addr) | 92 | __simd_vf__ inline void float_to_int16_vf(__ubuf__ int16_t* y_addr, __ubuf__ float* x_addr) |
| @@ -39,7 +39,7 @@ | |||
| 39 | 39 | ||
| 40 | **图1** 连续搬入矢量数据寄存器 | 40 | **图1** 连续搬入矢量数据寄存器 |
| 41 | 41 | ||
| 42 | - | 42 | + |
| 43 | 43 | ||
| 44 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 | 44 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 |
| 45 | 45 | ||
| @@ -36,7 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | **图1** 广播搬入矢量数据寄存器 | 37 | **图1** 广播搬入矢量数据寄存器 |
| 38 | 38 | ||
| 39 | - | 39 | + |
| 40 | 40 | ||
| 41 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 | 41 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 |
| 42 | 42 | ||
| @@ -32,7 +32,7 @@ | |||
| 32 | 32 | ||
| 33 | **图1** 广播搬入矢量数据寄存器 | 33 | **图1** 广播搬入矢量数据寄存器 |
| 34 | 34 | ||
| 35 | - | 35 | + |
| 36 | 36 | ||
| 37 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 | 37 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 |
| 38 | 38 | ||
| @@ -43,7 +43,7 @@ | |||
| 43 | 43 | ||
| 44 | **图1** 下采样搬入掩码寄存器 | 44 | **图1** 下采样搬入掩码寄存器 |
| 45 | 45 | ||
| 46 | - | 46 | + |
| 47 | 47 | ||
| 48 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 | 48 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 |
| 49 | 49 | ||
| @@ -35,7 +35,7 @@ | |||
| 35 | 35 | ||
| 36 | **图1** 下采样搬入掩码寄存器 | 36 | **图1** 下采样搬入掩码寄存器 |
| 37 | 37 | ||
| 38 | - | 38 | + |
| 39 | 39 | ||
| 40 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 | 40 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 |
| 41 | 41 | ||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | **图1** 连续搬入掩码寄存器 | 35 | **图1** 连续搬入掩码寄存器 |
| 36 | 36 | ||
| 37 | - | 37 | + |
| 38 | 38 | ||
| 39 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 | 39 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 |
| 40 | 40 | ||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | **图1** 下采样搬入掩码寄存器 | 35 | **图1** 下采样搬入掩码寄存器 |
| 36 | 36 | ||
| 37 | - | 37 | + |
| 38 | 38 | ||
| 39 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 | 39 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 |
| 40 | 40 | ||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | **图1** 上采样搬入掩码寄存器 | 35 | **图1** 上采样搬入掩码寄存器 |
| 36 | 36 | ||
| 37 | - | 37 | + |
| 38 | 38 | ||
| 39 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 | 39 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 |
| 40 | 40 | ||
| @@ -35,7 +35,7 @@ | |||
| 35 | 35 | ||
| 36 | **图1** 立即数偏移搬入模式 | 36 | **图1** 立即数偏移搬入模式 |
| 37 | 37 | ||
| 38 | - | 38 | + |
| 39 | 39 | ||
| 40 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 | 40 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 |
| 41 | 41 | ||
| @@ -36,7 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | **图1** 解包搬入矢量数据寄存器 | 37 | **图1** 解包搬入矢量数据寄存器 |
| 38 | 38 | ||
| 39 | - | 39 | + |
| 40 | 40 | ||
| 41 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 | 41 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 |
| 42 | 42 | ||
| @@ -32,7 +32,7 @@ | |||
| 32 | 32 | ||
| 33 | **图1** 解包搬入矢量数据寄存器 | 33 | **图1** 解包搬入矢量数据寄存器 |
| 34 | 34 | ||
| 35 | - | 35 | + |
| 36 | 36 | ||
| 37 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 | 37 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 |
| 38 | 38 | ||
| @@ -43,7 +43,7 @@ | |||
| 43 | 43 | ||
| 44 | **图1** 上采样搬入掩码寄存器 | 44 | **图1** 上采样搬入掩码寄存器 |
| 45 | 45 | ||
| 46 | - | 46 | + |
| 47 | 47 | ||
| 48 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 | 48 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 |
| 49 | 49 | ||
| @@ -35,7 +35,7 @@ | |||
| 35 | 35 | ||
| 36 | **图1** 上采样搬入掩码寄存器 | 36 | **图1** 上采样搬入掩码寄存器 |
| 37 | 37 | ||
| 38 | - | 38 | + |
| 39 | 39 | ||
| 40 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 | 40 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 |
| 41 | 41 | ||
| @@ -193,7 +193,7 @@ __simd_vf__ inline void load_align_post_update_vf(__ubuf__ half* dst, __ubuf__ h | |||
| 193 | 193 | ||
| 194 | **图1** 非对齐搬入示意图<a id="fig-loadunalign"></a> | 194 | **图1** 非对齐搬入示意图<a id="fig-loadunalign"></a> |
| 195 | 195 | ||
| 196 | - | 196 | + |
| 197 | 197 | ||
| 198 | 设有效起始字节地址为`src_start_addr`,将其向低地址方向按32字节对齐,得到`aligned_src_start_addr`。处理过程如下: | 198 | 设有效起始字节地址为`src_start_addr`,将其向低地址方向按32字节对齐,得到`aligned_src_start_addr`。处理过程如下: |
| 199 | 199 | ||
| @@ -218,13 +218,13 @@ __simd_vf__ inline void load_align_post_update_vf(__ubuf__ half* dst, __ubuf__ h | |||
| 218 | 218 | ||
| 219 | **图2** 非对齐搬出示意图(首次搬出)<a id="fig-storeunalign-empty"></a> | 219 | **图2** 非对齐搬出示意图(首次搬出)<a id="fig-storeunalign-empty"></a> |
| 220 | 220 | ||
| 221 | -") | 221 | +") |
| 222 | 222 | ||
| 223 | 首次搬出时,非对齐寄存器中没有前序尾块数据。主搬出接口将矢量数据寄存器中可直接写入的数据写入UB,并将末尾数据保存至非对齐寄存器。调用后处理接口后,尾块数据被写入UB。 | 223 | 首次搬出时,非对齐寄存器中没有前序尾块数据。主搬出接口将矢量数据寄存器中可直接写入的数据写入UB,并将末尾数据保存至非对齐寄存器。调用后处理接口后,尾块数据被写入UB。 |
| 224 | 224 | ||
| 225 | **图3** 非对齐搬出示意图(连续搬出)<a id="fig-storeunalign-cached"></a> | 225 | **图3** 非对齐搬出示意图(连续搬出)<a id="fig-storeunalign-cached"></a> |
| 226 | 226 | ||
| 227 | -") | 227 | +") |
| 228 | 228 | ||
| 229 | 后续连续搬出时,主搬出接口将非对齐寄存器中的前序尾块与本次矢量数据寄存器的主块数据拼接后写入UB,再将本次尾块更新至非对齐寄存器。连续搬出结束后,调用后处理接口写入最后一次缓存的尾块。 | 229 | 后续连续搬出时,主搬出接口将非对齐寄存器中的前序尾块与本次矢量数据寄存器的主块数据拼接后写入UB,再将本次尾块更新至非对齐寄存器。连续搬出结束后,调用后处理接口写入最后一次缓存的尾块。 |
| 230 | 230 | ||
| @@ -242,7 +242,7 @@ __simd_vf__ inline void load_align_post_update_vf(__ubuf__ half* dst, __ubuf__ h | |||
| 242 | 242 | ||
| 243 | **图4** 连续非对齐搬入搬出示例<a id="fig-loadstoreunalign"></a> | 243 | **图4** 连续非对齐搬入搬出示例<a id="fig-loadstoreunalign"></a> |
| 244 | 244 | ||
| 245 | - | 245 | + |
| 246 | 246 | ||
| 247 | ```c | 247 | ```c |
| 248 | __simd_vf__ inline void load_store_unalign_vf(__ubuf__ uint32_t* dst, __ubuf__ uint32_t* src, | 248 | __simd_vf__ inline void load_store_unalign_vf(__ubuf__ uint32_t* dst, __ubuf__ uint32_t* src, |
| @@ -44,7 +44,7 @@ $$ | |||
| 44 | \{carry_i, dst_i\} = \{1'b0, src0_i\} + \{1'b0, src1_i\} | 44 | \{carry_i, dst_i\} = \{1'b0, src0_i\} + \{1'b0, src1_i\} |
| 45 | $$ | 45 | $$ |
| 46 | 46 | ||
| 47 | - | 47 | + |
| 48 | 48 | ||
| 49 | 输出`carry`适用场景请参考[asc_addc功能说明](asc_addc.md#功能说明)。 | 49 | 输出`carry`适用场景请参考[asc_addc功能说明](asc_addc.md#功能说明)。 |
| 50 | 50 | ||
| @@ -38,7 +38,7 @@ $$ | |||
| 38 | \{carry_i, dst_i\} = \{1'b0, src0_i\} + \{1'b0, src1_i\} + \{32'b0, carry\_src_i\} | 38 | \{carry_i, dst_i\} = \{1'b0, src0_i\} + \{1'b0, src1_i\} + \{32'b0, carry\_src_i\} |
| 39 | $$ | 39 | $$ |
| 40 | 40 | ||
| 41 | - | 41 | + |
| 42 | 42 | ||
| 43 | 本接口为Reg矢量计算接口,仅在AIV上生效。 | 43 | 本接口为Reg矢量计算接口,仅在AIV上生效。 |
| 44 | 44 | ||
| @@ -97,7 +97,7 @@ __simd_callee__ inline void asc_addc(vector_bool& carry, | |||
| 97 | 97 | ||
| 98 | 以uint64_t类型数据计算0xFFFFFFFF FFFFFFFF + 0x00000000 00000008 = 0x00000000 00000007为例,asc_add/asc_addc接口的适用场景如下图: | 98 | 以uint64_t类型数据计算0xFFFFFFFF FFFFFFFF + 0x00000000 00000008 = 0x00000000 00000007为例,asc_add/asc_addc接口的适用场景如下图: |
| 99 | 99 | ||
| 100 | - | 100 | + |
| 101 | 101 | ||
| 102 | ## 调用示例 | 102 | ## 调用示例 |
| 103 | 103 | ||
| @@ -42,7 +42,7 @@ $$ | |||
| 42 | 42 | ||
| 43 | **图 1** asc_mull计算示意图 | 43 | **图 1** asc_mull计算示意图 |
| 44 | 44 | ||
| 45 | - | 45 | + |
🟡 Medium Priority 本片 diff 把 证据链:这三个文件位于 失败模式:文档站渲染时这三篇 experimental 文档的示意图变成断链缺图(图片 404),且与本文件中已改写的同名图形成“同图两套路径”的不一致。触发条件确定,无需特殊输入。 修复:将上述三处改为 建议:补全迁移剩余引用:将 ![]() ![]() Incorrect? | |||
| 46 | 46 | ||
| 47 | 本接口为Reg矢量计算接口,仅在AIV上生效。 | 47 | 本接口为Reg矢量计算接口,仅在AIV上生效。 |
| 48 | 48 | ||
| @@ -44,7 +44,7 @@ $$ | |||
| 44 | \{carry_i, dst_i\} = \{1'b0, src0_i\} + \{1'b0, \sim src1_i\} + 33'b1 | 44 | \{carry_i, dst_i\} = \{1'b0, src0_i\} + \{1'b0, \sim src1_i\} + 33'b1 |
| 45 | $$ | 45 | $$ |
| 46 | 46 | ||
| 47 | - | 47 | + |
| 48 | 48 | ||
| 49 | 输出`carry`适用场景请参考[asc_subc功能说明](asc_subc.md#功能说明)。 | 49 | 输出`carry`适用场景请参考[asc_subc功能说明](asc_subc.md#功能说明)。 |
| 50 | 50 | ||
| @@ -38,7 +38,7 @@ $$ | |||
| 38 | \{carry_i, dst_i\} = \{1'b0, src0_i\} + \{1'b0, \sim src1_i\} + \{32'b0, carry\_src_i\} | 38 | \{carry_i, dst_i\} = \{1'b0, src0_i\} + \{1'b0, \sim src1_i\} + \{32'b0, carry\_src_i\} |
| 39 | $$ | 39 | $$ |
| 40 | 40 | ||
| 41 | - | 41 | + |
| 42 | 42 | ||
| 43 | 本接口为Reg矢量计算接口,仅在AIV上生效。 | 43 | 本接口为Reg矢量计算接口,仅在AIV上生效。 |
| 44 | 44 | ||
| @@ -97,7 +97,7 @@ __simd_callee__ inline void asc_subc(vector_bool& carry, | |||
| 97 | 97 | ||
| 98 | 以uint64_t类型数据计算0xFFFFFFFF FFFFFFFF - 0x00000000 00000008 = 0xFFFFFFFF FFFFFFF7为例,asc_sub/asc_subc接口的适用场景如下图: | 98 | 以uint64_t类型数据计算0xFFFFFFFF FFFFFFFF - 0x00000000 00000008 = 0xFFFFFFFF FFFFFFF7为例,asc_sub/asc_subc接口的适用场景如下图: |
| 99 | 99 | ||
| 100 | - | 100 | + |
| 101 | 101 | ||
| 102 | ## 调用示例 | 102 | ## 调用示例 |
| 103 | 103 | ||
| @@ -146,11 +146,11 @@ __simd_callee__ inline void asc_copy(vector_bool& dst, | |||
| 146 | 146 | ||
| 147 | **图1** 矢量寄存器复制到掩码寄存器(uint16_t)<a id="fig-maskgen-b16"></a> | 147 | **图1** 矢量寄存器复制到掩码寄存器(uint16_t)<a id="fig-maskgen-b16"></a> |
| 148 | 148 | ||
| 149 | - | 149 | + |
| 150 | 150 | ||
| 151 | **图2** 矢量寄存器复制到掩码寄存器(uint32_t)<a id="fig-maskgen-b32"></a> | 151 | **图2** 矢量寄存器复制到掩码寄存器(uint32_t)<a id="fig-maskgen-b32"></a> |
| 152 | 152 | ||
| 153 | - | 153 | + |
| 154 | 154 | ||
| 155 | ## 调用示例 | 155 | ## 调用示例 |
| 156 | 156 | ||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | **图 1** 寄存器源收集模式 | 35 | **图 1** 寄存器源收集模式 |
| 36 | 36 | ||
| 37 | - | 37 | + |
| 38 | 38 | ||
| 39 | 本接口为Reg矢量计算接口,仅在AIV上生效。 | 39 | 本接口为Reg矢量计算接口,仅在AIV上生效。 |
| 40 | 40 | ||
| @@ -37,7 +37,7 @@ | |||
| 37 | 37 | ||
| 38 | 示例如下图所示: | 38 | 示例如下图所示: |
| 39 | 39 | ||
| 40 | - | 40 | + |
| 41 | 41 | ||
| 42 | 本接口为Reg矢量计算接口,仅在AIV上生效。 | 42 | 本接口为Reg矢量计算接口,仅在AIV上生效。 |
| 43 | 43 | ||
| @@ -37,7 +37,7 @@ | |||
| 37 | 37 | ||
| 38 | **图1** asc_create_mask原理 | 38 | **图1** asc_create_mask原理 |
| 39 | 39 | ||
| 40 | - | 40 | + |
| 41 | 41 | ||
| 42 | 本接口为Reg数据类型定义接口,仅在AIV上生效。 | 42 | 本接口为Reg数据类型定义接口,仅在AIV上生效。 |
| 43 | 43 | ||
| @@ -36,7 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | **图1** asc_update_mask更新流程 | 37 | **图1** asc_update_mask更新流程 |
| 38 | 38 | ||
| 39 | - | 39 | + |
| 40 | 40 | ||
| 41 | 本接口为Reg矢量计算接口,仅在AIV上生效。 | 41 | 本接口为Reg矢量计算接口,仅在AIV上生效。 |
| 42 | 42 | ||
| @@ -37,7 +37,7 @@ | |||
| 37 | 37 | ||
| 38 | **图1** 解交织实现流程 | 38 | **图1** 解交织实现流程 |
| 39 | 39 | ||
| 40 | - | 40 | + |
| 41 | 41 | ||
| 42 | 本接口为Reg矢量计算接口,仅在AIV上生效。 | 42 | 本接口为Reg矢量计算接口,仅在AIV上生效。 |
| 43 | 43 | ||
| @@ -35,7 +35,7 @@ | |||
| 35 | 35 | ||
| 36 | **图 1** int8_t类型交织过程 | 36 | **图 1** int8_t类型交织过程 |
| 37 | 37 | ||
| 38 | - | 38 | + |
| 39 | 39 | ||
| 40 | 本接口为Reg矢量计算接口,仅在AIV上生效。 | 40 | 本接口为Reg矢量计算接口,仅在AIV上生效。 |
| 41 | 41 | ||
| @@ -43,13 +43,13 @@ | |||
| 43 | 43 | ||
| 44 | **图1** 矢量数据寄存器unpack流程 | 44 | **图1** 矢量数据寄存器unpack流程 |
| 45 | 45 | ||
| 46 | - | 46 | + |
| 47 | 47 | ||
| 48 | 掩码数据寄存器unpack流程如图2所示: | 48 | 掩码数据寄存器unpack流程如图2所示: |
| 49 | 49 | ||
| 50 | **图2** 掩码数据寄存器unpack流程 | 50 | **图2** 掩码数据寄存器unpack流程 |
| 51 | 51 | ||
| 52 | - | 52 | + |
| 53 | 53 | ||
| 54 | 本接口为Reg矢量计算接口,仅在AIV上生效。 | 54 | 本接口为Reg矢量计算接口,仅在AIV上生效。 |
| 55 | 55 | ||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | **图1** unsqueeze流程 | 35 | **图1** unsqueeze流程 |
| 36 | 36 | ||
| 37 | - | 37 | + |
| 38 | 38 | ||
| 39 | 本接口为Reg矢量计算接口,仅在AIV上生效。 | 39 | 本接口为Reg矢量计算接口,仅在AIV上生效。 |
| 40 | 40 | ||
| @@ -31,7 +31,7 @@ | |||
| 31 | Reg矢量计算内不同流水线之间的同步指令。该同步指令指定源流水线和目的流水线,如下图所示,目的流水线将等待源流水线上所有指令完成才进行执行。 | 31 | Reg矢量计算内不同流水线之间的同步指令。该同步指令指定源流水线和目的流水线,如下图所示,目的流水线将等待源流水线上所有指令完成才进行执行。 |
| 32 | 读写场景下,当读指令使用的寄存器和写指令使用的寄存器相同时,可以触发寄存器保序,指令将会按照代码顺序执行,不需要插入同步指令,而当使用的寄存器不同时,如果要确保读写指令执行,则需要插入同步指令。写写场景同理。 | 32 | 读写场景下,当读指令使用的寄存器和写指令使用的寄存器相同时,可以触发寄存器保序,指令将会按照代码顺序执行,不需要插入同步指令,而当使用的寄存器不同时,如果要确保读写指令执行,则需要插入同步指令。写写场景同理。 |
| 33 | 33 | ||
| 34 | - | 34 | + |
| 35 | 35 | ||
| 36 | 本接口仅在AIV上生效。 | 36 | 本接口仅在AIV上生效。 |
| 37 | 37 | ||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | **图 1** UB源收集模式 | 35 | **图 1** UB源收集模式 |
| 36 | 36 | ||
| 37 | - | 37 | + |
| 38 | 38 | ||
| 39 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 | 39 | 本接口为Reg矢量搬运接口,仅在AIV上生效。 |
| 40 | 40 | ||
| @@ -134,7 +134,7 @@ __simd_callee__ inline vector_int16_t asc_gather(__ubuf__ int16_t* src, | |||
| 134 | 134 | ||
| 135 | - 当`src`与`dst`数据类型一致,但是与`index`数据类型不一致时,数据写入`dst`索引为偶数的位置,奇数索引位置置零。例如`src`为`int8_t`数据类型,`index`为`uint16_t`数据类型时,适用场景如下图: | 135 | - 当`src`与`dst`数据类型一致,但是与`index`数据类型不一致时,数据写入`dst`索引为偶数的位置,奇数索引位置置零。例如`src`为`int8_t`数据类型,`index`为`uint16_t`数据类型时,适用场景如下图: |
| 136 | 136 | ||
| 137 | - | 137 | + |
| 138 | 138 | ||
| 139 | ## 调用示例 | 139 | ## 调用示例 |
| 140 | 140 | ||
| @@ -30,7 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | 给定源操作数在Unified Buffer(UB)中的基地址和索引,根据索引位置将源操作数按DataBlock收集到目的操作数中。每个DataBlock长度为32B。 | 31 | 给定源操作数在Unified Buffer(UB)中的基地址和索引,根据索引位置将源操作数按DataBlock收集到目的操作数中。每个DataBlock长度为32B。 |
| 32 | 32 | ||
| 33 | - | 33 | + |
| 34 | 34 | ||
| 35 | 其中,index中仅前8个元素有效,每个元素对应一个DataBlock。例如,第一个元素为96(3 * 32),表示选取DataBlock3写入dst中对应的位置。 | 35 | 其中,index中仅前8个元素有效,每个元素对应一个DataBlock。例如,第一个元素为96(3 * 32),表示选取DataBlock3写入dst中对应的位置。 |
| 36 | 36 | ||
| @@ -45,7 +45,7 @@ AIC 0中在执行asc_sync_intra_wait后,此时AIC 0 sync_id=0的计数器为0 | |||
| 45 | - AIV 0-1的PIPE_MTE3指令全部执行完毕后,asc_sync_intra_arrive生效。此时调度模块感知1个AIV已执行完asc_sync_intra_arrive,因此将AIC 0 sync_id=0的计数器值增加为1。AIC 0检测到对应的sync_id=0的计数器变为1,则AIC 0核解除阻塞,继续执行后续PIPE_FIX的指令,并且将计数器值减去1。 | 45 | - AIV 0-1的PIPE_MTE3指令全部执行完毕后,asc_sync_intra_arrive生效。此时调度模块感知1个AIV已执行完asc_sync_intra_arrive,因此将AIC 0 sync_id=0的计数器值增加为1。AIC 0检测到对应的sync_id=0的计数器变为1,则AIC 0核解除阻塞,继续执行后续PIPE_FIX的指令,并且将计数器值减去1。 |
| 46 | 46 | ||
| 47 | **图1** block内同步时序图(AIV进行asc_sync_intra_arrive) | 47 | **图1** block内同步时序图(AIV进行asc_sync_intra_arrive) |
| 48 | -") | 48 | +") |
| 49 | 49 | ||
| 50 | 核间同步具体使用方法,请参考[调用示例](#调用示例)。 | 50 | 核间同步具体使用方法,请参考[调用示例](#调用示例)。 |
| 51 | 51 | ||
| @@ -57,7 +57,7 @@ AIC0中在执行`asc_sync_inter_wait`后,此时AIC0 `flag_id=0`的计数器为 | |||
| 57 | AIC1的`asc_sync_inter_arrive`执行完后,此时调度模块感知到2个AIC均已执行完`asc_sync_inter_arrive`,因此所有AIC各自的`flag_id=0`的计数器值增加为1。AIC0和AIC1检测到各自对应的`flag_id=0`的计数器变为1,都解除PIPE_FIX流水后续指令的阻塞,继续执行后续指令,并且将计数器值减去1。 | 57 | AIC1的`asc_sync_inter_arrive`执行完后,此时调度模块感知到2个AIC均已执行完`asc_sync_inter_arrive`,因此所有AIC各自的`flag_id=0`的计数器值增加为1。AIC0和AIC1检测到各自对应的`flag_id=0`的计数器变为1,都解除PIPE_FIX流水后续指令的阻塞,继续执行后续指令,并且将计数器值减去1。 |
| 58 | 58 | ||
| 59 | **图2** 模式0:多AI Core中AIC全核同步<a id="multi_ai_core_aic_full_sync"></a> | 59 | **图2** 模式0:多AI Core中AIC全核同步<a id="multi_ai_core_aic_full_sync"></a> |
| 60 | - | 60 | + |
| 61 | <!-- end id1 --> | 61 | <!-- end id1 --> |
| 62 | 62 | ||
| 63 | <!-- npu="A3,910b" id2 --> | 63 | <!-- npu="A3,910b" id2 --> |
| @@ -94,7 +94,7 @@ AIV0-0中在执行`asc_sync_subblock_wait`后,此时AIV0-0 `flag_id=0`的计 | |||
| 94 | AIV0-1的`asc_sync_subblock_arrive`执行完后,此时调度模块感知到2个AIV均已执行完`asc_sync_subblock_arrive`,因此将AIV0-0和AIV0-1各自的`flag_id=0`的计数器值增加为1。AIV0-0和AIV0-1检测到各自对应的`flag_id=0`的计数器变为1,都解除所有流水后续指令的阻塞,继续执行后续指令,并且将计数器值减去1。 | 94 | AIV0-1的`asc_sync_subblock_arrive`执行完后,此时调度模块感知到2个AIV均已执行完`asc_sync_subblock_arrive`,因此将AIV0-0和AIV0-1各自的`flag_id=0`的计数器值增加为1。AIV0-0和AIV0-1检测到各自对应的`flag_id=0`的计数器变为1,都解除所有流水后续指令的阻塞,继续执行后续指令,并且将计数器值减去1。 |
| 95 | 95 | ||
| 96 | **图3** 模式1:单个AI Core中AIV全核同步<a id="single_ai_core_aiv_full_sync_diagram"></a> | 96 | **图3** 模式1:单个AI Core中AIV全核同步<a id="single_ai_core_aiv_full_sync_diagram"></a> |
| 97 | - | 97 | + |
| 98 | <!-- end id2 --> | 98 | <!-- end id2 --> |
| 99 | 99 | ||
| 100 | <!-- npu="950" id3 --> | 100 | <!-- npu="950" id3 --> |
| @@ -145,7 +145,7 @@ AIC0中在执行`asc_sync_block_wait`后,此时AIC0 `flag_id=0`的计数器为 | |||
| 145 | 当AIV0-0的Vector指令1、2全部执行完毕后,前置PIPE\_V的指令全部完成,`asc_sync_block_arrive`生效。此时调度模块感知到2个AIV均已执行完`asc_sync_block_arrive`,因此将AIC0 `flag_id=0`的计数器值增加为1。AIC0检测到对应的`flag_id=0`的计数器变为1,则AIC0核解除PIPE_MTE2流水后续指令的阻塞,继续执行后续指令Matrix指令2,并且将计数器值减去1。 | 145 | 当AIV0-0的Vector指令1、2全部执行完毕后,前置PIPE\_V的指令全部完成,`asc_sync_block_arrive`生效。此时调度模块感知到2个AIV均已执行完`asc_sync_block_arrive`,因此将AIC0 `flag_id=0`的计数器值增加为1。AIC0检测到对应的`flag_id=0`的计数器变为1,则AIC0核解除PIPE_MTE2流水后续指令的阻塞,继续执行后续指令Matrix指令2,并且将计数器值减去1。 |
| 146 | 146 | ||
| 147 | **图4** 模式2:单个AI Core中AIC与AIV全核同步(AIV进行asc_sync_block_arrive)<a id="single_ai_core_aic_aiv_full_sync_diagram"></a> | 147 | **图4** 模式2:单个AI Core中AIC与AIV全核同步(AIV进行asc_sync_block_arrive)<a id="single_ai_core_aic_aiv_full_sync_diagram"></a> |
| 148 | -") | 148 | +") |
| 149 | <!-- end id3 --> | 149 | <!-- end id3 --> |
| 150 | 150 | ||
| 151 | <!-- npu="950" id4 --> | 151 | <!-- npu="950" id4 --> |
| @@ -192,5 +192,5 @@ AIC0中在执行`asc_sync_intra_wait`后,此时AIC0 `sync_id=16`的计数器 | |||
| 192 | - AIV0-1的PIPE_MTE3指令全部执行完毕后,`asc_sync_intra_arrive`生效。此时调度模块感知1个AIV已执行完`asc_sync_intra_arrive`,因此将AIC0 `sync_id=16`的计数器值增加为1。AIC0检测到对应的`sync_id=16`的计数器变为1,则AIC0核解除由`pipe`参数指定的流水后续指令的阻塞,继续执行后续PIPE_FIX的指令,并且将计数器值减去1。 | 192 | - AIV0-1的PIPE_MTE3指令全部执行完毕后,`asc_sync_intra_arrive`生效。此时调度模块感知1个AIV已执行完`asc_sync_intra_arrive`,因此将AIC0 `sync_id=16`的计数器值增加为1。AIC0检测到对应的`sync_id=16`的计数器变为1,则AIC0核解除由`pipe`参数指定的流水后续指令的阻塞,继续执行后续PIPE_FIX的指令,并且将计数器值减去1。 |
| 193 | 193 | ||
| 194 | **图5** 模式4:单个AI Core中AIC与单个AIV同步(AIV进行asc_sync_intra_arrive)<a id="single_ai_core_aic_single_aiv_sync_diagram"></a> | 194 | **图5** 模式4:单个AI Core中AIC与单个AIV同步(AIV进行asc_sync_intra_arrive)<a id="single_ai_core_aic_single_aiv_sync_diagram"></a> |
| 195 | -") | 195 | +") |
| 196 | <!-- end id4 --> | 196 | <!-- end id4 --> |
| @@ -34,7 +34,7 @@ | |||
| 34 | - `asc_sync_wait`:当目的流水执行到该指令时,如果发现硬件中对应标志位为0,目的流水的后续指令将一直被阻塞;如果发现硬件中对应标志位为1,则将硬件中对应标志位设置为0,同时目的流水的后续指令开始执行。 | 34 | - `asc_sync_wait`:当目的流水执行到该指令时,如果发现硬件中对应标志位为0,目的流水的后续指令将一直被阻塞;如果发现硬件中对应标志位为1,则将硬件中对应标志位设置为0,同时目的流水的后续指令开始执行。 |
| 35 | 35 | ||
| 36 | **图1** `asc_sync_notify`和`asc_sync_wait`接口功能示意图 | 36 | **图1** `asc_sync_notify`和`asc_sync_wait`接口功能示意图 |
| 37 | - | 37 | + |
| 38 | 38 | ||
| 39 | ## 函数原型 | 39 | ## 函数原型 |
| 40 | 40 | ||
| @@ -36,7 +36,7 @@ | |||
| 36 | 如图1所示,其作用是保证指定流水线中前序指令的所有数据读写全部完成后,该流水的后序指令才能开始执行。 | 36 | 如图1所示,其作用是保证指定流水线中前序指令的所有数据读写全部完成后,该流水的后序指令才能开始执行。 |
| 37 | 37 | ||
| 38 | **图1** `asc_sync_pipe`接口功能示意图 | 38 | **图1** `asc_sync_pipe`接口功能示意图 |
| 39 | - | 39 | + |
| 40 | 40 | ||
| 41 | ## 函数原型 | 41 | ## 函数原型 |
| 42 | 42 | ||
| @@ -34,7 +34,7 @@ | |||
| 34 | - `asc_sync_wait`:当目的流水执行到该指令时,如果发现硬件中对应标志位为0,目的流水的后续指令将一直被阻塞;如果发现硬件中对应标志位为1,则将硬件中对应标志位设置为0,同时目的流水的后续指令开始执行。 | 34 | - `asc_sync_wait`:当目的流水执行到该指令时,如果发现硬件中对应标志位为0,目的流水的后续指令将一直被阻塞;如果发现硬件中对应标志位为1,则将硬件中对应标志位设置为0,同时目的流水的后续指令开始执行。 |
| 35 | 35 | ||
| 36 | **图1** `asc_sync_notify`和`asc_sync_wait`接口功能示意图 | 36 | **图1** `asc_sync_notify`和`asc_sync_wait`接口功能示意图 |
| 37 | - | 37 | + |
| 38 | 38 | ||
| 39 | ## 函数原型 | 39 | ## 函数原型 |
| 40 | 40 | ||
| @@ -35,7 +35,7 @@ | |||
| 35 | - asc_deq_int162b8_l:将数据存放在每个DataBlock的低半块。 | 35 | - asc_deq_int162b8_l:将数据存放在每个DataBlock的低半块。 |
| 36 | 36 | ||
| 37 | 如下图所示: | 37 | 如下图所示: |
| 38 | - | 38 | + |
| 39 | 39 | ||
| 40 | 计算公式如下: | 40 | 计算公式如下: |
| 41 | 41 | ||
| @@ -32,15 +32,15 @@ | |||
| 32 | 32 | ||
| 33 | 单次repeat内转换规则如下: | 33 | 单次repeat内转换规则如下: |
| 34 | 34 | ||
| 35 | -- 当输入数据类型位宽为16位时,每个DataBlock中包含16个数,指令内部会循环16次,每次循环都会分别从指定的16个DataBlock中的对应位置取值,组成一个新的DataBlock单元放入目的地址中。如下图所示,图中的srcList[0]-srcList[15]代表源操作数的16个DataBlock。 | 35 | +- 当输入数据类型位宽为16位时,每个DataBlock中包含16个数,指令内部会循环16次,每次循环都会分别从指定的16个DataBlock中的对应位置取值,组成一个新的DataBlock单元放入目的地址中。如下图所示,图中的srcList[0]-srcList[15]代表源操作数的16个DataBlock。 |
| 36 | 36 | ||
| 37 | -- 当数据类型位宽为32位时,每个DataBlock包含8个数,指令内部会循环8次,每次循环都会分别从指定的16个DataBlock中的对应位置取值,组成2个新的DataBlock放入目的地址中。如下图所示: | 37 | +- 当数据类型位宽为32位时,每个DataBlock包含8个数,指令内部会循环8次,每次循环都会分别从指定的16个DataBlock中的对应位置取值,组成2个新的DataBlock放入目的地址中。如下图所示: |
| 38 | 38 | ||
| 39 | -- 当数据类型位宽为8位时,每个DataBlock包含32个数,指令内部会循环16次,每次循环都会分别从指定的16个DataBlock中的对应位置取值,组成半个DataBlock放入目的地址中,读取和存放是在DataBlock的高半部还是低半部由参数srcHighHalf和dstHighHalf决定。如下图所示: | 39 | +- 当数据类型位宽为8位时,每个DataBlock包含32个数,指令内部会循环16次,每次循环都会分别从指定的16个DataBlock中的对应位置取值,组成半个DataBlock放入目的地址中,读取和存放是在DataBlock的高半部还是低半部由参数srcHighHalf和dstHighHalf决定。如下图所示: |
| 40 | 40 | ||
| 41 | 基于以上的转换规则,使用该接口进行NC1HWC0格式转换或者矩阵转置。NC1HWC0格式转换相对复杂,这里给出其具体的转换方法: | 41 | 基于以上的转换规则,使用该接口进行NC1HWC0格式转换或者矩阵转置。NC1HWC0格式转换相对复杂,这里给出其具体的转换方法: |
| 42 | 42 | ||
| 43 | -NCHW格式转换成NC1HWC0格式时,如果是数据类型的位宽为32位或者16位,则C0=16;如果数据类型的位宽为8位,则C0=32。下图以C0=16为例进行介绍: | 43 | +NCHW格式转换成NC1HWC0格式时,如果是数据类型的位宽为32位或者16位,则C0=16;如果数据类型的位宽为8位,则C0=32。下图以C0=16为例进行介绍: |
| 44 | 44 | ||
| 45 | ## 函数原型 | 45 | ## 函数原型 |
| 46 | 46 | ||
| @@ -36,11 +36,11 @@ | |||
| 36 | 36 | ||
| 37 | **图1** 连续搬运示意图 | 37 | **图1** 连续搬运示意图 |
| 38 | 38 | ||
| 39 | - | 39 | + |
| 40 | 40 | ||
| 41 | **图2** 高维切分搬运示意图 | 41 | **图2** 高维切分搬运示意图 |
| 42 | 42 | ||
| 43 | - | 43 | + |
| 44 | 44 | ||
| 45 | 本接口仅在AIV上生效。 | 45 | 本接口仅在AIV上生效。 |
| 46 | 46 | ||
| @@ -56,11 +56,11 @@ | |||
| 56 | 56 | ||
| 57 | **图1** Compact模式32字节补齐示意图 | 57 | **图1** Compact模式32字节补齐示意图 |
| 58 | 58 | ||
| 59 | -  | 59 | +  |
| 60 | 60 | ||
| 61 | **图2** Normal模式32字节补齐示意图 | 61 | **图2** Normal模式32字节补齐示意图 |
| 62 | 62 | ||
| 63 | -  | 63 | +  |
| 64 | 64 | ||
| 65 | 当只搬运1个数据块,或`burst_len`已经32字节对齐且无左右Padding时,两种模式的搬运结果相同。 | 65 | 当只搬运1个数据块,或`burst_len`已经32字节对齐且无左右Padding时,两种模式的搬运结果相同。 |
| 66 | 66 | ||
| @@ -35,10 +35,10 @@ | |||
| 35 | 有效长度非32字节对齐时,硬件会补齐读取UB至32字节边界,但仅把有效数据写入GM。连续搬运仅在整体末尾补齐读取;高维切分搬运中,`src_stride`等于`burst_len`时仅在所有数据块的整体末尾补齐读取,否则每个数据块分别补齐读取。源UB必须为实际读取范围预留合法空间。 | 35 | 有效长度非32字节对齐时,硬件会补齐读取UB至32字节边界,但仅把有效数据写入GM。连续搬运仅在整体末尾补齐读取;高维切分搬运中,`src_stride`等于`burst_len`时仅在所有数据块的整体末尾补齐读取,否则每个数据块分别补齐读取。源UB必须为实际读取范围预留合法空间。 |
| 36 | 36 | ||
| 37 | **图1** 连续搬运示意图 | 37 | **图1** 连续搬运示意图 |
| 38 | - | 38 | + |
| 39 | 39 | ||
| 40 | **图2** 高维切分搬运示意图 | 40 | **图2** 高维切分搬运示意图 |
| 41 | - | 41 | + |
| 42 | 42 | ||
| 43 | 本接口仅在AIV上生效。 | 43 | 本接口仅在AIV上生效。 |
| 44 | 44 | ||
| @@ -50,10 +50,10 @@ | |||
| 50 | - Normal模式下将`src_stride`设置为64,各数据块在UB中的起始偏移依次为0、64、128,每个数据块分别补充16字节dummy假数据。 | 50 | - Normal模式下将`src_stride`设置为64,各数据块在UB中的起始偏移依次为0、64、128,每个数据块分别补充16字节dummy假数据。 |
| 51 | 51 | ||
| 52 | **图1** Compact模式32字节对齐读数示意图 | 52 | **图1** Compact模式32字节对齐读数示意图 |
| 53 | -  | 53 | +  |
| 54 | 54 | ||
| 55 | **图2** Normal模式32字节对齐读数示意图 | 55 | **图2** Normal模式32字节对齐读数示意图 |
| 56 | -  | 56 | +  |
| 57 | 57 | ||
| 58 | 两种模式下,dummy假数据均不会写入GM。当只搬运1个数据块,或`burst_len`已经32字节对齐时,两种模式的搬运结果相同。 | 58 | 两种模式下,dummy假数据均不会写入GM。当只搬运1个数据块,或`burst_len`已经32字节对齐时,两种模式的搬运结果相同。 |
| 59 | 59 | ||
| @@ -37,14 +37,14 @@ | |||
| 37 | 将一段连续数据从UB搬运到L1 Buffer,如图1所示。 | 37 | 将一段连续数据从UB搬运到L1 Buffer,如图1所示。 |
| 38 | 38 | ||
| 39 | **图1** 连续搬运示意图 | 39 | **图1** 连续搬运示意图 |
| 40 | -  | 40 | +  |
| 41 | 41 | ||
| 42 | - 高维切分数据搬运 | 42 | - 高维切分数据搬运 |
| 43 | 43 | ||
| 44 | 将多个连续传输数据块从UB搬运到L1 Buffer。每个数据块的长度以及相邻数据块之间的间隔均以DataBlock(32字节)为单位指定,如图2所示。 | 44 | 将多个连续传输数据块从UB搬运到L1 Buffer。每个数据块的长度以及相邻数据块之间的间隔均以DataBlock(32字节)为单位指定,如图2所示。 |
| 45 | 45 | ||
| 46 | **图2** 高维切分搬运示意图 | 46 | **图2** 高维切分搬运示意图 |
| 47 | -  | 47 | +  |
| 48 | 48 | ||
| 49 | 本接口仅在AIV上生效。 | 49 | 本接口仅在AIV上生效。 |
| 50 | 50 | ||
| @@ -33,10 +33,10 @@ | |||
| 33 | 本接口支持连续数据搬运和高维切分数据搬运。连续数据搬运按`size`指定的字节数在UB内连续搬运,如图1所示;高维切分数据搬运按`burst_count`指定搬运的数据块个数,每个数据块按`burst_len`指定的DataBlock个数搬运,并通过`src_gap`和`dst_gap`指定源操作数和目的操作数相邻数据块之间的间隔,如图2所示。 | 33 | 本接口支持连续数据搬运和高维切分数据搬运。连续数据搬运按`size`指定的字节数在UB内连续搬运,如图1所示;高维切分数据搬运按`burst_count`指定搬运的数据块个数,每个数据块按`burst_len`指定的DataBlock个数搬运,并通过`src_gap`和`dst_gap`指定源操作数和目的操作数相邻数据块之间的间隔,如图2所示。 |
| 34 | 34 | ||
| 35 | **图1** 连续搬运示意图 | 35 | **图1** 连续搬运示意图 |
| 36 | - | 36 | + |
| 37 | 37 | ||
| 38 | **图2** 高维切分搬运示意图 | 38 | **图2** 高维切分搬运示意图 |
| 39 | - | 39 | + |
| 40 | 40 | ||
| 41 | 本接口仅在AIV上生效。 | 41 | 本接口仅在AIV上生效。 |
| 42 | 42 | ||
| @@ -59,7 +59,7 @@ PIPE_MTE2 | |||
| 59 | ## 调用示例 | 59 | ## 调用示例 |
| 60 | 60 | ||
| 61 | 2D Padding场景,使用固定值填充方式 | 61 | 2D Padding场景,使用固定值填充方式 |
| 62 | - | 62 | + |
| 63 | 63 | ||
| 64 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[\_\_NPU\_ARCH\_\_](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 | 64 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[\_\_NPU\_ARCH\_\_](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 |
| 65 | 65 | ||
| @@ -52,19 +52,19 @@ | |||
| 52 | 以下以2维的例子,介绍几个典型使用场景。 | 52 | 以下以2维的例子,介绍几个典型使用场景。 |
| 53 | 53 | ||
| 54 | - 2D Padding场景,使用固定值填充方式 | 54 | - 2D Padding场景,使用固定值填充方式 |
| 55 | - | 55 | + |
| 56 | 56 | ||
| 57 | - 2D Padding场景,使用最近值填充方式 | 57 | - 2D Padding场景,使用最近值填充方式 |
| 58 | - | 58 | + |
| 59 | 59 | ||
| 60 | - 2D Transpose场景 | 60 | - 2D Transpose场景 |
| 61 | - | 61 | + |
| 62 | 62 | ||
| 63 | - 2D Slice场景 | 63 | - 2D Slice场景 |
| 64 | - | 64 | + |
| 65 | 65 | ||
| 66 | - 2D Broadcast场景 | 66 | - 2D Broadcast场景 |
| 67 | - | 67 | + |
| 68 | 68 | ||
| 69 | 本接口仅在AIV上生效。 | 69 | 本接口仅在AIV上生效。 |
| 70 | 70 | ||
| @@ -147,7 +147,7 @@ PIPE_MTE2 | |||
| 147 | ## 调用示例 | 147 | ## 调用示例 |
| 148 | 148 | ||
| 149 | 2D Padding场景,使用固定值填充方式 | 149 | 2D Padding场景,使用固定值填充方式 |
| 150 | - | 150 | + |
| 151 | 151 | ||
| 152 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[\_\_NPU\_ARCH\_\_](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 | 152 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[\_\_NPU\_ARCH\_\_](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 |
| 153 | 153 | ||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | 以源操作数搬运场景为例,如下图所示。 | 35 | 以源操作数搬运场景为例,如下图所示。 |
| 36 | 36 | ||
| 37 | - | 37 | + |
| 38 | 38 | ||
| 39 | 本接口仅在AIV上生效。 | 39 | 本接口仅在AIV上生效。 |
| 40 | 40 | ||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | 以源操作数搬运场景为例,如下图所示。 | 35 | 以源操作数搬运场景为例,如下图所示。 |
| 36 | 36 | ||
| 37 | - | 37 | + |
| 38 | 38 | ||
| 39 | 本接口仅在AIV上生效。 | 39 | 本接口仅在AIV上生效。 |
| 40 | 40 | ||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | 以源操作数搬运场景为例,如下图所示。 | 35 | 以源操作数搬运场景为例,如下图所示。 |
| 36 | 36 | ||
| 37 | - | 37 | + |
| 38 | 38 | ||
| 39 | 本接口仅在AIV上生效。 | 39 | 本接口仅在AIV上生效。 |
| 40 | 40 | ||
| @@ -36,7 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | 以源操作数搬运场景为例,如下图所示。 | 37 | 以源操作数搬运场景为例,如下图所示。 |
| 38 | 38 | ||
| 39 | - | 39 | + |
| 40 | 40 | ||
| 41 | ## 函数原型 | 41 | ## 函数原型 |
| 42 | 42 | ||
| @@ -36,7 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | 以源操作数搬运场景为例,如下图所示。 | 37 | 以源操作数搬运场景为例,如下图所示。 |
| 38 | 38 | ||
| 39 | - | 39 | + |
| 40 | 40 | ||
| 41 | ## 函数原型 | 41 | ## 函数原型 |
| 42 | 42 | ||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | 以源操作数搬运场景为例,如下图所示。 | 35 | 以源操作数搬运场景为例,如下图所示。 |
| 36 | 36 | ||
| 37 | - | 37 | + |
| 38 | 38 | ||
| 39 | 本接口仅在AIV上执行有效,在AIC上调用为空操作。 | 39 | 本接口仅在AIV上执行有效,在AIC上调用为空操作。 |
| 40 | 40 | ||
| @@ -75,13 +75,13 @@ __simd_callee__ inline reg_tensor<bool> move_mask(const reg_tensor<T>& src) | |||
| 75 | 75 | ||
| 76 | **图1** uint16_t矢量数据寄存器生成掩码寄存器<a id="fig-move-mask-b16"></a> | 76 | **图1** uint16_t矢量数据寄存器生成掩码寄存器<a id="fig-move-mask-b16"></a> |
| 77 | 77 | ||
| 78 | - | 78 | + |
| 79 | 79 | ||
| 80 | `T`为`uint32_t`时,每个元素对应掩码寄存器中的4bit,且仅4bit中的最低位有效。选中的8B数据块包含64bit,每个bit扩展为4bit后生成一个32B掩码寄存器。一个256B源寄存器包含32个数据块,因此`Offset`取值范围为[0, 31]。 | 80 | `T`为`uint32_t`时,每个元素对应掩码寄存器中的4bit,且仅4bit中的最低位有效。选中的8B数据块包含64bit,每个bit扩展为4bit后生成一个32B掩码寄存器。一个256B源寄存器包含32个数据块,因此`Offset`取值范围为[0, 31]。 |
| 81 | 81 | ||
| 82 | **图2** uint32_t矢量数据寄存器生成掩码寄存器<a id="fig-move-mask-b32"></a> | 82 | **图2** uint32_t矢量数据寄存器生成掩码寄存器<a id="fig-move-mask-b32"></a> |
| 83 | 83 | ||
| 84 | - | 84 | + |
| 85 | 85 | ||
| 86 | ## 调用示例 | 86 | ## 调用示例 |
| 87 | 87 | ||


🟡 Medium Priority
本次改动把 c_api 目录下所有图片引用从
c_api/figures改写到docs/zh/api/figures(本行由figures/unsupported_address_overlap_example.png改为../../figures/...,deprecated_interface 改为../../../figures/...,reg_compute/load 改为../../../../figures/...),PR 描述同时声明「已验证指向 c_api/figures 的图片引用清零」「原目录清空」。但在同一目录树内仍有 3 个未随本次改动更新的文件,保持旧写法
../figures/...,它们解析到的正是被清空的c_api/figures:对照证据:相同图片在迁移后的路径已被其它文件使用(reg_arith/asc_mull.md:45 →
../../../../figures/asc_mull.png、reg_permute_sel/asc_intlv.md:38、reg_permute_sel/asc_deintlv.md:40 →../../../../figures/capi_deintlv_reg.png),说明这些图片的权威副本已位于api/figures;本次迁移(把 c_api/figures 清空/去重)恰好抽掉了 experimental 三处引用的目标文件。失效模式:
c_api/figures被清空后,上述 3 个页面渲染时图片缺失(CI 图片链接校验也会失败),与 PR 自述的「引用清零/无缺失链接」结论矛盾。属于本次一侧改动造成的跨文件不一致。修复:把这 3 处改为../../figures/<同名文件>(experimental 相对 api/figures 需要上溯 2 级),并重新跑一次全仓图片引用存在性检查以覆盖c_api之外可能存在的同类残留。建议:将 docs/zh/api/SIMD-API/c_api/experimental/asc_mull.md:47、asc_intlv.md:40、asc_deintlv.md:42 的
../figures/...分别改为../../figures/asc_mull.png、../../figures/asc_intlv.png、../../figures/capi_deintlv_reg.png,确保 c_api/figures 清空后无残留死链。