已合并
docs: add blank lines around headings in docs/zh to meet format rules #6515
ai_xin创建于 19 天前
docs: add blank lines around headings in docs/zh to meet format rules #6515
已合并
共 107 个文件变更+189-0
| @@ -26,6 +26,7 @@ uint32_t SetReduceType(uint32_t reduceType, uint8_t dstDataType = 0, uint8_t src | |||
| 26 | - 非0表示设置失败。 | 26 | - 非0表示设置失败。 |
| 27 | 27 | ||
| 28 | ## 约束说明 | 28 | ## 约束说明 |
| 29 | + | ||
| 29 | <!-- npu="950" id3 --> | 30 | <!-- npu="950" id3 --> |
| 30 | 对于Ascend 950PR&950DT系列产品,AI CPU作为服务端时,该接口暂不支持使用。 | 31 | 对于Ascend 950PR&950DT系列产品,AI CPU作为服务端时,该接口暂不支持使用。 |
| 31 | <!-- end id3 --> | 32 | <!-- end id3 --> |
| @@ -39,6 +39,7 @@ enum class MatrixMadType : int32_t { | |||
| 39 | 无 | 39 | 无 |
| 40 | 40 | ||
| 41 | <!-- npu="950" id3 --> | 41 | <!-- npu="950" id3 --> |
| 42 | + | ||
| 42 | ## 调用示例 | 43 | ## 调用示例 |
| 43 | 44 | ||
| 44 | ``` | 45 | ``` |
| @@ -1,6 +1,7 @@ | |||
| 1 | # 辅助矩阵分形格式详解<a name="ZH-CN_TOPIC_0000002538231118"></a> | 1 | # 辅助矩阵分形格式详解<a name="ZH-CN_TOPIC_0000002538231118"></a> |
| 2 | 2 | ||
| 3 | <!-- npu="950" id1 --> | 3 | <!-- npu="950" id1 --> |
| 4 | + | ||
| 4 | ## MX系数矩阵<a name="zh-cn_topic_0000002563445163_section648585413300"></a> | 5 | ## MX系数矩阵<a name="zh-cn_topic_0000002563445163_section648585413300"></a> |
| 5 | 6 | ||
| 6 | 针对Ascend 950PR&950DT系列产品产品: | 7 | 针对Ascend 950PR&950DT系列产品产品: |
| @@ -71,6 +72,7 @@ MXMmad为带有量化系数X的矩阵乘法,即左矩阵和右矩阵均有对 | |||
| 71 | <!-- end id1 --> | 72 | <!-- end id1 --> |
| 72 | 73 | ||
| 73 | <!-- npu="A3,910b" id2 --> | 74 | <!-- npu="A3,910b" id2 --> |
| 75 | + | ||
| 74 | ## 4选2稀疏索引矩阵<a name="zh-cn_topic_0000002563445163_section1873692415233"></a> | 76 | ## 4选2稀疏索引矩阵<a name="zh-cn_topic_0000002563445163_section1873692415233"></a> |
| 75 | 77 | ||
| 76 | 针对Atlas A2训练系列产品/Atlas A2推理系列产品和Atlas A3训练系列产品/Atlas A3推理系列产品: | 78 | 针对Atlas A2训练系列产品/Atlas A2推理系列产品和Atlas A3训练系列产品/Atlas A3推理系列产品: |
| @@ -76,6 +76,7 @@ | |||
| 76 | <!-- end id20 --> | 76 | <!-- end id20 --> |
| 77 | 77 | ||
| 78 | <!-- npu="910b,A3,310b,310p,910,x90,9030" id10 --> | 78 | <!-- npu="910b,A3,310b,310p,910,x90,9030" id10 --> |
| 79 | + | ||
| 79 | ## Zz格式(FRACTAL_Zz)<a name="zh-cn_topic_0000002545089965_section1798516571585"></a> | 80 | ## Zz格式(FRACTAL_Zz)<a name="zh-cn_topic_0000002545089965_section1798516571585"></a> |
| 80 | 81 | ||
| 81 | - **定义:** 大Z外部row major(行主序)+ 小z内部row major(行主序),见[图4](#zh-cn_topic_0000002545089965_fig18376432205510)。 | 82 | - **定义:** 大Z外部row major(行主序)+ 小z内部row major(行主序),见[图4](#zh-cn_topic_0000002545089965_fig18376432205510)。 |
| @@ -156,6 +156,7 @@ Kirin X90处理器系列产品,支持数据类型:int8_t、half。 | |||
| 156 | <!-- npu="950" id19 --> | 156 | <!-- npu="950" id19 --> |
| 157 | - 针对Ascend 950PR&950DT系列产品,推荐使用LoadData2dTransposeParamsV2作为参数,该参数具有更精细的搬运粒度。 | 157 | - 针对Ascend 950PR&950DT系列产品,推荐使用LoadData2dTransposeParamsV2作为参数,该参数具有更精细的搬运粒度。 |
| 158 | <!-- end id19 --> | 158 | <!-- end id19 --> |
| 159 | + | ||
| 159 | ## 关键特性说明<a id="zh-cn_topic_0000002543851571_section1891111310132"></a> | 160 | ## 关键特性说明<a id="zh-cn_topic_0000002543851571_section1891111310132"></a> |
| 160 | 161 | ||
| 161 | ### 功能和参数讲解 | 162 | ### 功能和参数讲解 |
| @@ -514,6 +515,7 @@ for (int i = 0; i < CeilDivision(k, fractalShape[0]); ++i) { | |||
| 514 | ``` | 515 | ``` |
| 515 | 516 | ||
| 516 | <!-- npu="950" id20 --> | 517 | <!-- npu="950" id20 --> |
| 518 | + | ||
| 517 | ### 使用LoadData2dTransposeParamsV2结构体作为参数的场景示例 | 519 | ### 使用LoadData2dTransposeParamsV2结构体作为参数的场景示例 |
| 518 | 520 | ||
| 519 | 该示例使用了LoadData2dTransposeParamsV2结构体作为参数,输入a矩阵为int8_t类型,shape为[128,128],输入数据格式为NZ,输入b矩阵为int8_t类型,shape为[128,256],输入数据格式为NZ,输出c的类型为float。a矩阵从L1 Buffer(A1)搬运到L0A Buffer(A2)且不转置,b矩阵从L1 Buffer(B1)搬运到L0B Buffer(B2)并转置,示例仅展示接口调用过程,其余计算和搬运不作参考。完整示例请参考:[load_data_l12l0样例](../../../../../../../examples/01_simd_cpp_api/03_basic_api/03_matrix_compute/load_data_l12l0)。 | 521 | 该示例使用了LoadData2dTransposeParamsV2结构体作为参数,输入a矩阵为int8_t类型,shape为[128,128],输入数据格式为NZ,输入b矩阵为int8_t类型,shape为[128,256],输入数据格式为NZ,输出c的类型为float。a矩阵从L1 Buffer(A1)搬运到L0A Buffer(A2)且不转置,b矩阵从L1 Buffer(B1)搬运到L0B Buffer(B2)并转置,示例仅展示接口调用过程,其余计算和搬运不作参考。完整示例请参考:[load_data_l12l0样例](../../../../../../../examples/01_simd_cpp_api/03_basic_api/03_matrix_compute/load_data_l12l0)。 |
| @@ -32,6 +32,7 @@ LoadDataWithSparse主要用于搬运以512Byte为单位存放的稠密权重矩 | |||
| 32 | 矩阵计算过程中,常用分形支持总结如下表: | 32 | 矩阵计算过程中,常用分形支持总结如下表: |
| 33 | 33 | ||
| 34 | <!-- npu="910b,A3" id2 --> | 34 | <!-- npu="910b,A3" id2 --> |
| 35 | + | ||
| 35 | ### 针对Atlas A2训练系列产品/Atlas A2推理系列产品和Atlas A3训练系列产品/Atlas A3推理系列产品 | 36 | ### 针对Atlas A2训练系列产品/Atlas A2推理系列产品和Atlas A3训练系列产品/Atlas A3推理系列产品 |
| 36 | 37 | ||
| 37 | 常用分形支持情况如下,供开发者参考: | 38 | 常用分形支持情况如下,供开发者参考: |
| @@ -119,6 +120,7 @@ LoadDataWithSparse主要用于搬运以512Byte为单位存放的稠密权重矩 | |||
| 119 | <!-- end id2 --> | 120 | <!-- end id2 --> |
| 120 | 121 | ||
| 121 | <!-- npu="950" id3 --> | 122 | <!-- npu="950" id3 --> |
| 123 | + | ||
| 122 | ### 针对Ascend 950PR&950DT系列产品 | 124 | ### 针对Ascend 950PR&950DT系列产品 |
| 123 | 125 | ||
| 124 | DataCopy(GM-\>L1 Buffer)支持使能随路进行DN到NZ转换,一定会改变分形排布。 | 126 | DataCopy(GM-\>L1 Buffer)支持使能随路进行DN到NZ转换,一定会改变分形排布。 |
| @@ -203,6 +203,7 @@ DataCopy矩阵搬出接口支持多种随路能力的组合,需要设置不同 | |||
| 203 | <!-- end id24 --> | 203 | <!-- end id24 --> |
| 204 | 204 | ||
| 205 | <!-- npu="950,A3,910b" id25 --> | 205 | <!-- npu="950,A3,910b" id25 --> |
| 206 | + | ||
| 206 | ## 调用示例<a id="zh-cn_topic_0000002511188540_section088124295117"></a> | 207 | ## 调用示例<a id="zh-cn_topic_0000002511188540_section088124295117"></a> |
| 207 | 208 | ||
| 208 | 示例:通路L0C Buffer->L1 Buffer。输入A矩阵和B矩阵的数据类型为half,输出C矩阵为int8_t,不开启NZ2ND的格式转换,开启scalar量化。 | 209 | 示例:通路L0C Buffer->L1 Buffer。输入A矩阵和B矩阵的数据类型为half,输出C矩阵为int8_t,不开启NZ2ND的格式转换,开启scalar量化。 |
| @@ -203,6 +203,7 @@ L0C Buffer到UB数据搬运提供矩阵搬出的组合接口Fixpipe,接口内 | |||
| 203 | <!-- end id18 --> | 203 | <!-- end id18 --> |
| 204 | 204 | ||
| 205 | <!-- npu="950" id20 --> | 205 | <!-- npu="950" id20 --> |
| 206 | + | ||
| 206 | ## 关键特性说明 | 207 | ## 关键特性说明 |
| 207 | 208 | ||
| 208 | 以下图片和说明仅适用于Ascend 950PR&950DT系列产品: | 209 | 以下图片和说明仅适用于Ascend 950PR&950DT系列产品: |
| @@ -110,6 +110,7 @@ src和dst分别为源操作数和目的操作数;intriParams为ND2NZ搬运配 | |||
| 110 | <!-- end id1 --> | 110 | <!-- end id1 --> |
| 111 | 111 | ||
| 112 | <!-- npu="950" id2 --> | 112 | <!-- npu="950" id2 --> |
| 113 | + | ||
| 113 | ## DataCopy(GMToL1随路转换-DN2NZ搬运)<a name="ZH-CN_TOPIC_0000002573902899"></a> | 114 | ## DataCopy(GMToL1随路转换-DN2NZ搬运)<a name="ZH-CN_TOPIC_0000002573902899"></a> |
| 114 | 115 | ||
| 115 | 该接口主要实现将数据从Global Memory搬运至L1 Buffer,并支持在数据搬运时进行[DN](../cube_compute_ISASI/cube_compute_fractal_intro/key_fractal_format_details.md)到[NZ](../cube_compute_ISASI/cube_compute_fractal_intro/key_fractal_format_details.md)格式的转换。 | 116 | 该接口主要实现将数据从Global Memory搬运至L1 Buffer,并支持在数据搬运时进行[DN](../cube_compute_ISASI/cube_compute_fractal_intro/key_fractal_format_details.md)到[NZ](../cube_compute_ISASI/cube_compute_fractal_intro/key_fractal_format_details.md)格式的转换。 |
| @@ -132,6 +133,7 @@ src和dst分别为源操作数和目的操作数;intriParams为DN2NZ搬运配 | |||
| 132 | <!-- end id2 --> | 133 | <!-- end id2 --> |
| 133 | 134 | ||
| 134 | <!-- npu="950" id3 --> | 135 | <!-- npu="950" id3 --> |
| 136 | + | ||
| 135 | ## DataCopyPad(GMToL1非对齐数据搬运)<a name="ZH-CN_TOPIC_0000002543262891"></a> | 137 | ## DataCopyPad(GMToL1非对齐数据搬运)<a name="ZH-CN_TOPIC_0000002543262891"></a> |
| 136 | 138 | ||
| 137 | 该接口主要实现将数据从Global Memory搬运至L1 Buffer,并支持在数据搬运时提供非对齐数据搬运功能,可以根据开发者的需要自行填充数据。 | 139 | 该接口主要实现将数据从Global Memory搬运至L1 Buffer,并支持在数据搬运时提供非对齐数据搬运功能,可以根据开发者的需要自行填充数据。 |
| @@ -172,6 +174,7 @@ __aicore__ inline void LoadData(const LocalTensor<T>& dst, const GlobalTensor<T> | |||
| 172 | ``` | 174 | ``` |
| 173 | 175 | ||
| 174 | <!-- npu="950" id4 --> | 176 | <!-- npu="950" id4 --> |
| 177 | + | ||
| 175 | ## GMToL1 NZ数据搬运(LoadData(2D矩阵搬运V2)) | 178 | ## GMToL1 NZ数据搬运(LoadData(2D矩阵搬运V2)) |
| 176 | 179 | ||
| 177 | 该接口主要实现将数据从Global Memory搬运至L1 Buffer,负责完成普通矩阵计算所需的2D格式数据的搬运,以大小为512Byte的数据分形为单位进行搬运。 | 180 | 该接口主要实现将数据从Global Memory搬运至L1 Buffer,负责完成普通矩阵计算所需的2D格式数据的搬运,以大小为512Byte的数据分形为单位进行搬运。 |
| @@ -43,6 +43,7 @@ __aicore__ inline void LoadData(const LocalTensor<T>& dst, const LocalTensor<T>& | |||
| 43 | ``` | 43 | ``` |
| 44 | 44 | ||
| 45 | <!-- npu="950" id1 --> | 45 | <!-- npu="950" id1 --> |
| 46 | + | ||
| 46 | ## L1ToL0A 2D格式分形矩阵搬运(LoadData(2D矩阵搬运V2)) | 47 | ## L1ToL0A 2D格式分形矩阵搬运(LoadData(2D矩阵搬运V2)) |
| 47 | 48 | ||
| 48 | LoadData(2D矩阵搬运V2)能够实现L1 Buffer到L0A Buffer之间的数据搬运。负责完成普通矩阵计算所需的2D格式数据的搬运,以大小为512Byte的数据分形为单位进行搬运。 | 49 | LoadData(2D矩阵搬运V2)能够实现L1 Buffer到L0A Buffer之间的数据搬运。负责完成普通矩阵计算所需的2D格式数据的搬运,以大小为512Byte的数据分形为单位进行搬运。 |
| @@ -65,6 +66,7 @@ src和dst分别为源操作数和目的操作数;loadDataParams为搬运参数 | |||
| 65 | <!-- end id1 --> | 66 | <!-- end id1 --> |
| 66 | 67 | ||
| 67 | <!-- npu="950" id2 --> | 68 | <!-- npu="950" id2 --> |
| 69 | + | ||
| 68 | ## L1ToL0A 2D格式分形矩阵搬运(LoadData(MX矩阵搬运)) | 70 | ## L1ToL0A 2D格式分形矩阵搬运(LoadData(MX矩阵搬运)) |
| 69 | 71 | ||
| 70 | LoadData(MX矩阵搬运)负责完成矩阵计算所需的左右矩阵数据和对应的左右量化系数矩阵数据的搬运,其中左右矩阵数据以大小为512Byte的数据分形为单位进行搬运,左右量化系数矩阵以32Byte的数据分形为单位进行搬运。 | 72 | LoadData(MX矩阵搬运)负责完成矩阵计算所需的左右矩阵数据和对应的左右量化系数矩阵数据的搬运,其中左右矩阵数据以大小为512Byte的数据分形为单位进行搬运,左右量化系数矩阵以32Byte的数据分形为单位进行搬运。 |
| @@ -157,6 +159,7 @@ src和dst分别为源操作数和目的操作数;loadDataParams为搬运参数 | |||
| 157 | <!-- end id3 --> | 159 | <!-- end id3 --> |
| 158 | 160 | ||
| 159 | <!-- npu="950" id1 --> | 161 | <!-- npu="950" id1 --> |
| 162 | + | ||
| 160 | ## L1ToL0A 3D格式分形矩阵搬运(LoadDataWithStride)<a name="ZH-CN_TOPIC_0000002573312819"></a> | 163 | ## L1ToL0A 3D格式分形矩阵搬运(LoadDataWithStride)<a name="ZH-CN_TOPIC_0000002573312819"></a> |
| 161 | 164 | ||
| 162 | LoadDataWithStride用于将NC1HWC0格式的Feature Map完成Image to Column展开,然后再从展开后的二维矩阵中选取指定数据块搬入对应内存位置,支持配置输出矩阵K轴方向偏移量。 | 165 | LoadDataWithStride用于将NC1HWC0格式的Feature Map完成Image to Column展开,然后再从展开后的二维矩阵中选取指定数据块搬入对应内存位置,支持配置输出矩阵K轴方向偏移量。 |
| @@ -197,6 +200,7 @@ __aicore__ inline void LoadData(const LocalTensor<T>& dst, const LocalTensor<T>& | |||
| 197 | ``` | 200 | ``` |
| 198 | 201 | ||
| 199 | <!-- npu="950" id4 --> | 202 | <!-- npu="950" id4 --> |
| 203 | + | ||
| 200 | ## L1ToL0B 2D格式分形矩阵搬运(LoadData(2D矩阵搬运V2)) | 204 | ## L1ToL0B 2D格式分形矩阵搬运(LoadData(2D矩阵搬运V2)) |
| 201 | 205 | ||
| 202 | LoadData(2D矩阵搬运V2)能够实现L1 Buffer到L0B Buffer之间的数据搬运。负责完成普通矩阵计算所需的2D格式数据的搬运,以大小为512Byte的数据分形为单位进行搬运。 | 206 | LoadData(2D矩阵搬运V2)能够实现L1 Buffer到L0B Buffer之间的数据搬运。负责完成普通矩阵计算所需的2D格式数据的搬运,以大小为512Byte的数据分形为单位进行搬运。 |
| @@ -219,6 +223,7 @@ src和dst分别为源操作数和目的操作数;loadDataParams为搬运参数 | |||
| 219 | <!-- end id4 --> | 223 | <!-- end id4 --> |
| 220 | 224 | ||
| 221 | <!-- npu="950" id5 --> | 225 | <!-- npu="950" id5 --> |
| 226 | + | ||
| 222 | ## L1ToL0B 2D格式分形矩阵搬运(LoadData(MX矩阵搬运)) | 227 | ## L1ToL0B 2D格式分形矩阵搬运(LoadData(MX矩阵搬运)) |
| 223 | 228 | ||
| 224 | LoadData(MX矩阵搬运)负责完成矩阵计算所需的左右矩阵数据和对应的左右量化系数矩阵数据的搬运,其中左右矩阵数据以大小为512Byte的数据分形为单位进行搬运,左右量化系数矩阵以32Byte的数据分形为单位进行搬运。 | 229 | LoadData(MX矩阵搬运)负责完成矩阵计算所需的左右矩阵数据和对应的左右量化系数矩阵数据的搬运,其中左右矩阵数据以大小为512Byte的数据分形为单位进行搬运,左右量化系数矩阵以32Byte的数据分形为单位进行搬运。 |
| @@ -311,6 +316,7 @@ src和dst分别为源操作数和目的操作数;loadDataParams为搬运参数 | |||
| 311 | <!-- end id6 --> | 316 | <!-- end id6 --> |
| 312 | 317 | ||
| 313 | <!-- npu="950" id12 --> | 318 | <!-- npu="950" id12 --> |
| 319 | + | ||
| 314 | ## L1ToL0B 3D格式分形矩阵搬运(LoadDataWithStride)<a name="ZH-CN_TOPIC_0000002573312819"></a> | 320 | ## L1ToL0B 3D格式分形矩阵搬运(LoadDataWithStride)<a name="ZH-CN_TOPIC_0000002573312819"></a> |
| 315 | 321 | ||
| 316 | LoadDataWithStride用于将NC1HWC0格式的Feature Map完成Image to Column展开,然后再从展开后的二维矩阵中选取指定数据块搬入对应内存位置,支持配置输出矩阵K轴方向偏移量。 | 322 | LoadDataWithStride用于将NC1HWC0格式的Feature Map完成Image to Column展开,然后再从展开后的二维矩阵中选取指定数据块搬入对应内存位置,支持配置输出矩阵K轴方向偏移量。 |
| @@ -333,6 +339,7 @@ src和dst分别为源操作数和目的操作数;loadDataParams为搬运参数 | |||
| 333 | <!-- end id12 --> | 339 | <!-- end id12 --> |
| 334 | 340 | ||
| 335 | <!-- npu="A3,910b" id9 --> | 341 | <!-- npu="A3,910b" id9 --> |
| 342 | + | ||
| 336 | ## L1ToL0B 稠密权重矩阵搬运(LoadDataWithSparse)<a name="ZH-CN_TOPIC_0000002574022821"></a> | 343 | ## L1ToL0B 稠密权重矩阵搬运(LoadDataWithSparse)<a name="ZH-CN_TOPIC_0000002574022821"></a> |
| 337 | 344 | ||
| 338 | 用于从L1中搬运以512Byte为单位存放的稠密权重矩阵到L0B里,同时搬运以128Byte为单位的索引矩阵到内置的专用buffer空间(用于后续MmadWithSparse接口进行读取)。 | 345 | 用于从L1中搬运以512Byte为单位存放的稠密权重矩阵到L0B里,同时搬运以128Byte为单位的索引矩阵到内置的专用buffer空间(用于后续MmadWithSparse接口进行读取)。 |
| @@ -92,6 +92,7 @@ __aicore__ inline void DataCopyPad(const LocalTensor<T>& dst, const LocalTensor< | |||
| 92 | ``` | 92 | ``` |
| 93 | 93 | ||
| 94 | <!-- npu="310p" id1 --> | 94 | <!-- npu="310p" id1 --> |
| 95 | + | ||
| 95 | ## DataCopy(L0CToUB随路量化激活搬运) | 96 | ## DataCopy(L0CToUB随路量化激活搬运) |
| 96 | 97 | ||
| 97 | 该接口主要实现将数据从L0C Buffer搬运至UB,并支持多种随路能力的组合,接口内包含了设置寄存器与数据搬运能力。 | 98 | 该接口主要实现将数据从L0C Buffer搬运至UB,并支持多种随路能力的组合,接口内包含了设置寄存器与数据搬运能力。 |
| @@ -152,6 +153,7 @@ src和dst分别为源操作数和目的操作数;intriParams为搬运参数, | |||
| 152 | ``` | 153 | ``` |
| 153 | 154 | ||
| 154 | <!-- npu="950" id2 --> | 155 | <!-- npu="950" id2 --> |
| 156 | + | ||
| 155 | ## DataCopyL1ToUB(L1ToUB连续数据搬运) | 157 | ## DataCopyL1ToUB(L1ToUB连续数据搬运) |
| 156 | 158 | ||
| 157 | DataCopyL1ToUB能够实现L1 Buffer到UB的连续数据搬运,数据搬运时格式和内容保持不变。 | 159 | DataCopyL1ToUB能够实现L1 Buffer到UB的连续数据搬运,数据搬运时格式和内容保持不变。 |
| @@ -174,6 +176,7 @@ __aicore__ inline void DataCopyL1ToUB(const LocalTensor<T>& dst, const LocalTens | |||
| 174 | <!-- end id2 --> | 176 | <!-- end id2 --> |
| 175 | 177 | ||
| 176 | <!-- npu="950" id3 --> | 178 | <!-- npu="950" id3 --> |
| 179 | + | ||
| 177 | ## DataCopyL1ToUB(L1ToUB高维切分数据搬运) | 180 | ## DataCopyL1ToUB(L1ToUB高维切分数据搬运) |
| 178 | 181 | ||
| 179 | DataCopyL1ToUB能够实现L1 Buffer到UB的连续数据搬运和非连续数据搬运,数据搬运时格式和内容保持不变。 | 182 | DataCopyL1ToUB能够实现L1 Buffer到UB的连续数据搬运和非连续数据搬运,数据搬运时格式和内容保持不变。 |
| @@ -381,6 +381,7 @@ $$ | |||
| 381 | | 0 | 8'hFE | 23'h7FFFFF | 最大正规格数 | | 381 | | 0 | 8'hFE | 23'h7FFFFF | 最大正规格数 | |
| 382 | 382 | ||
| 383 | <!-- npu="950" id1 --> | 383 | <!-- npu="950" id1 --> |
| 384 | + | ||
| 384 | ## 复数<a name="section8666633175111"></a> | 385 | ## 复数<a name="section8666633175111"></a> |
| 385 | 386 | ||
| 386 | Ascend C提供了复数数据类型:complex32和complex64。 | 387 | Ascend C提供了复数数据类型:complex32和complex64。 |
| @@ -208,6 +208,7 @@ $dst_i = src0_i / src1_i$ | |||
| 208 | <!-- end id32 --> | 208 | <!-- end id32 --> |
| 209 | 209 | ||
| 210 | <!-- npu="950" id35 --> | 210 | <!-- npu="950" id35 --> |
| 211 | + | ||
| 211 | ## 关键特性<a id="div-key-features"></a> | 212 | ## 关键特性<a id="div-key-features"></a> |
| 212 | 213 | ||
| 213 | 针对Ascend 950PR&950DT系列产品,有如下关键特性: | 214 | 针对Ascend 950PR&950DT系列产品,有如下关键特性: |
| @@ -178,6 +178,7 @@ T支持的数据类型为:half、float。 | |||
| 178 | <!-- end id21 --> | 178 | <!-- end id21 --> |
| 179 | 179 | ||
| 180 | <!-- npu="950" id24 --> | 180 | <!-- npu="950" id24 --> |
| 181 | + | ||
| 181 | ## 关键特性<a id="exp-key-features"></a> | 182 | ## 关键特性<a id="exp-key-features"></a> |
| 182 | 183 | ||
| 183 | 针对Ascend 950PR&950DT系列产品,有如下关键特性: | 184 | 针对Ascend 950PR&950DT系列产品,有如下关键特性: |
| @@ -180,6 +180,7 @@ T支持的数据类型为:half、float。 | |||
| 180 | <!-- end id21 --> | 180 | <!-- end id21 --> |
| 181 | 181 | ||
| 182 | <!-- npu="950" id24 --> | 182 | <!-- npu="950" id24 --> |
| 183 | + | ||
| 183 | ## 关键特性<a id="ln-key-features"></a> | 184 | ## 关键特性<a id="ln-key-features"></a> |
| 184 | 185 | ||
| 185 | 针对Ascend 950PR&950DT系列产品,有如下关键特性: | 186 | 针对Ascend 950PR&950DT系列产品,有如下关键特性: |
| @@ -204,6 +204,7 @@ $dst_i = \frac{1}{src_i}$ | |||
| 204 | - 使用Reciprocal时,half的算子结果对比误差不满足双千分之一的要求,float的算子结果对比误差不满足双万分之一的要求,如果需要高精度,建议使用[Div](Div.md)替代实现。 | 204 | - 使用Reciprocal时,half的算子结果对比误差不满足双千分之一的要求,float的算子结果对比误差不满足双万分之一的要求,如果需要高精度,建议使用[Div](Div.md)替代实现。 |
| 205 | 205 | ||
| 206 | <!-- npu="950" id35 --> | 206 | <!-- npu="950" id35 --> |
| 207 | + | ||
| 207 | ## 关键特性<a id="reciprocal-key-features"></a> | 208 | ## 关键特性<a id="reciprocal-key-features"></a> |
| 208 | 209 | ||
| 209 | 针对Ascend 950PR&950DT系列产品,有如下关键特性: | 210 | 针对Ascend 950PR&950DT系列产品,有如下关键特性: |
| @@ -181,6 +181,7 @@ T支持的数据类型为:half、float。 | |||
| 181 | - 使用Rsqrt时,half的算子结果对比误差不满足双千分之一的要求,float的算子结果对比误差不满足双万分之一的要求,如果需要高精度,建议使用[Div](Div.md)和[Sqrt](Sqrt.md)替代实现。 | 181 | - 使用Rsqrt时,half的算子结果对比误差不满足双千分之一的要求,float的算子结果对比误差不满足双万分之一的要求,如果需要高精度,建议使用[Div](Div.md)和[Sqrt](Sqrt.md)替代实现。 |
| 182 | 182 | ||
| 183 | <!-- npu="950" id35 --> | 183 | <!-- npu="950" id35 --> |
| 184 | + | ||
| 184 | ## 关键特性<a id="rsqrt-key-features"></a> | 185 | ## 关键特性<a id="rsqrt-key-features"></a> |
| 185 | 186 | ||
| 186 | 针对Ascend 950PR&950DT系列产品,有如下关键特性: | 187 | 针对Ascend 950PR&950DT系列产品,有如下关键特性: |
| @@ -181,6 +181,7 @@ T支持的数据类型为:half、float。 | |||
| 181 | - 如果src中的数值为非正数,可能会产生未知结果。 | 181 | - 如果src中的数值为非正数,可能会产生未知结果。 |
| 182 | 182 | ||
| 183 | <!-- npu="950" id35 --> | 183 | <!-- npu="950" id35 --> |
| 184 | + | ||
| 184 | ## 关键特性<a id="sqrt-key-features"></a> | 185 | ## 关键特性<a id="sqrt-key-features"></a> |
| 185 | 186 | ||
| 186 | 针对Ascend 950PR&950DT系列产品,有如下关键特性: | 187 | 针对Ascend 950PR&950DT系列产品,有如下关键特性: |
| @@ -59,6 +59,7 @@ __aicore__ inline void AbsSub(const LocalTensor<T> &dst, const LocalTensor<T> &s | |||
| 59 | | count | 输入 | 参与计算的元素个数。 | | 59 | | count | 输入 | 参与计算的元素个数。 | |
| 60 | 60 | ||
| 61 | ## 数据类型 | 61 | ## 数据类型 |
| 62 | + | ||
| 62 | <!-- npu="950" id8 --> | 63 | <!-- npu="950" id8 --> |
| 63 | Ascend 950PR&950DT系列产品,T支持的数据类型为:half、float。 | 64 | Ascend 950PR&950DT系列产品,T支持的数据类型为:half、float。 |
| 64 | <!-- end id8 --> | 65 | <!-- end id8 --> |
| @@ -64,6 +64,7 @@ __aicore__ inline void ExpSub(const LocalTensor<T>& dst, const LocalTensor<U>& s | |||
| 64 | | count | 输入 | 参与计算的元素个数。 | | 64 | | count | 输入 | 参与计算的元素个数。 | |
| 65 | 65 | ||
| 66 | ## 数据类型 | 66 | ## 数据类型 |
| 67 | + | ||
| 67 | <!-- npu="950" id8 --> | 68 | <!-- npu="950" id8 --> |
| 68 | Ascend 950PR&950DT系列产品,T和U支持的数据类型为:half、float。 | 69 | Ascend 950PR&950DT系列产品,T和U支持的数据类型为:half、float。 |
| 69 | <!-- end id8 --> | 70 | <!-- end id8 --> |
| @@ -84,6 +84,7 @@ __aicore__ inline void MulsCast(const T2 &dst, const T3 &src0, const T4 &src1, c | |||
| 84 | | float | half | 将源操作数按照CAST_ROUND模式取到half所能表示的数,以half格式(溢出默认按照饱和处理)存入dst中。 | | 84 | | float | half | 将源操作数按照CAST_ROUND模式取到half所能表示的数,以half格式(溢出默认按照饱和处理)存入dst中。 | |
| 85 | 85 | ||
| 86 | ## 数据类型 | 86 | ## 数据类型 |
| 87 | + | ||
| 87 | <!-- npu="950" id8 --> | 88 | <!-- npu="950" id8 --> |
| 88 | Ascend 950PR&950DT系列产品,src支持的数据类型为:float。dst支持的数据类型为:half。 | 89 | Ascend 950PR&950DT系列产品,src支持的数据类型为:float。dst支持的数据类型为:half。 |
| 89 | <!-- end id8 --> | 90 | <!-- end id8 --> |
| @@ -140,6 +140,7 @@ __aicore__ inline void Brcb(const LocalTensor<T>& dst, const LocalTensor<T>& src | |||
| 140 | - 针对Ascend 950PR&950DT系列产品,该接口通过VF调用[Reg矢量计算API](../../reg_vector_compute/reg_vector_compute.md)实现兼容,当参数repeatTime取值为0时,不保证该接口将被视为NOP(空操作)。 | 140 | - 针对Ascend 950PR&950DT系列产品,该接口通过VF调用[Reg矢量计算API](../../reg_vector_compute/reg_vector_compute.md)实现兼容,当参数repeatTime取值为0时,不保证该接口将被视为NOP(空操作)。 |
| 141 | <!-- end id21 --> | 141 | <!-- end id21 --> |
| 142 | <!-- end id17 --> | 142 | <!-- end id17 --> |
| 143 | + | ||
| 143 | ## 关键特性说明 | 144 | ## 关键特性说明 |
| 144 | 145 | ||
| 145 | 源操作数不支持Stride参数配置,始终采用连续读。 | 146 | 源操作数不支持Stride参数配置,始终采用连续读。 |
| @@ -165,6 +165,7 @@ $dst_i = src0_i \& src1_i$ | |||
| 165 | - 针对Ascend 950PR&950DT系列产品,该接口通过VF调用[Reg矢量计算API](../../reg_vector_compute/reg_vector_compute.md)实现兼容,当参数count或repeatTime取值为0时,不保证该接口将被视为NOP(空操作)。 | 165 | - 针对Ascend 950PR&950DT系列产品,该接口通过VF调用[Reg矢量计算API](../../reg_vector_compute/reg_vector_compute.md)实现兼容,当参数count或repeatTime取值为0时,不保证该接口将被视为NOP(空操作)。 |
| 166 | <!-- end id30 --> | 166 | <!-- end id30 --> |
| 167 | <!-- end id26 --> | 167 | <!-- end id26 --> |
| 168 | + | ||
| 168 | ## 调用示例<a name="section642mcpsimp"></a> | 169 | ## 调用示例<a name="section642mcpsimp"></a> |
| 169 | 170 | ||
| 170 | - tensor高维切分计算样例-mask连续模式 | 171 | - tensor高维切分计算样例-mask连续模式 |
| @@ -58,6 +58,7 @@ __aicore__ inline void ShiftLeft(const LocalTensor<T>& dst, const LocalTensor<T> | |||
| 58 | | count | 输入 | 参与计算的元素个数。 | | 58 | | count | 输入 | 参与计算的元素个数。 | |
| 59 | 59 | ||
| 60 | ## 数据类型 | 60 | ## 数据类型 |
| 61 | + | ||
| 61 | <!-- npu="950" id8 --> | 62 | <!-- npu="950" id8 --> |
| 62 | Ascend 950PR&950DT系列产品,T支持的数据类型为:int8_t、uint8_t、int16_t、uint16_t、int32_t、uint32_t、int64_t、uint64_t。U支持的数据类型为:int8_t、int16_t、int32_t、int64_t。 | 63 | Ascend 950PR&950DT系列产品,T支持的数据类型为:int8_t、uint8_t、int16_t、uint16_t、int32_t、uint32_t、int64_t、uint64_t。U支持的数据类型为:int8_t、int16_t、int32_t、int64_t。 |
| 63 | <!-- end id8 --> | 64 | <!-- end id8 --> |
| @@ -68,6 +68,7 @@ __aicore__ inline void ShiftRight(const LocalTensor<T>& dst, const LocalTensor<T | |||
| 68 | 68 | ||
| 69 | 69 | ||
| 70 | ## 数据类型 | 70 | ## 数据类型 |
| 71 | + | ||
| 71 | <!-- npu="950" id8 --> | 72 | <!-- npu="950" id8 --> |
| 72 | Ascend 950PR&950DT系列产品,T支持的数据类型为:int8_t、uint8_t、int16_t、uint16_t、int32_t、uint32_t、int64_t、uint64_t。U支持的数据类型为:int8_t、int16_t、int32_t、int64_t。 | 73 | Ascend 950PR&950DT系列产品,T支持的数据类型为:int8_t、uint8_t、int16_t、uint16_t、int32_t、uint32_t、int64_t、uint64_t。U支持的数据类型为:int8_t、int16_t、int32_t、int64_t。 |
| 73 | <!-- end id8 --> | 74 | <!-- end id8 --> |
| @@ -91,6 +91,7 @@ | |||
| 91 | **注:以上高维切分相关参数`mask`,`repeatTime`,`srcRepStride`请参考[高维切分](../SIMD_compute/high_dim_split.md)中的介绍。** | 91 | **注:以上高维切分相关参数`mask`,`repeatTime`,`srcRepStride`请参考[高维切分](../SIMD_compute/high_dim_split.md)中的介绍。** |
| 92 | 92 | ||
| 93 | ## 数据类型 | 93 | ## 数据类型 |
| 94 | + | ||
| 94 | 支持的数据类型如下: | 95 | 支持的数据类型如下: |
| 95 | 96 | ||
| 96 | <!-- npu="950" id10 --> | 97 | <!-- npu="950" id10 --> |
| @@ -90,6 +90,7 @@ def Gather(dst, src, count, srcOffset, srcBaseAddr): | |||
| 90 | | dstRepStride | 输入 | 相邻迭代间的地址步长,单位是DataBlock(32Bytes)。 | | 90 | | dstRepStride | 输入 | 相邻迭代间的地址步长,单位是DataBlock(32Bytes)。 | |
| 91 | 91 | ||
| 92 | ## 数据类型 | 92 | ## 数据类型 |
| 93 | + | ||
| 93 | <!-- npu="950" id8 --> | 94 | <!-- npu="950" id8 --> |
| 94 | Ascend 950PR&950DT系列产品,支持的数据类型为:int8_t、uint8_t、int16_t、uint16_t、half、bfloat16_t、int32_t、uint32_t、float、int64_t、uint64_t。数据类型int8\_t、uint8\_t仅支持tensor前n个数据计算接口。 | 95 | Ascend 950PR&950DT系列产品,支持的数据类型为:int8_t、uint8_t、int16_t、uint16_t、half、bfloat16_t、int32_t、uint32_t、float、int64_t、uint64_t。数据类型int8\_t、uint8\_t仅支持tensor前n个数据计算接口。 |
| 95 | <!-- end id8 --> | 96 | <!-- end id8 --> |
| @@ -149,6 +149,7 @@ Atlas 200I/500 A2推理产品,支持的数据类型为:int8_t、uint8_t、in | |||
| 149 | - Atlas A2系列产品 | 149 | - Atlas A2系列产品 |
| 150 | <!-- end id20 --> | 150 | <!-- end id20 --> |
| 151 | <!-- end id18 --> | 151 | <!-- end id18 --> |
| 152 | + | ||
| 152 | ## 调用示例<a name="section11276201527"></a> | 153 | ## 调用示例<a name="section11276201527"></a> |
| 153 | 154 | ||
| 154 | 完整使用样例请参见[Gather类样例](../../../../../../../examples/01_simd_cpp_api/03_basic_api/01_memory_vector_compute/gather)场景四。 | 155 | 完整使用样例请参见[Gather类样例](../../../../../../../examples/01_simd_cpp_api/03_basic_api/01_memory_vector_compute/gather)场景四。 |
| @@ -57,6 +57,7 @@ __aicore__ inline void Truncate(const LocalTensor<T> &dst, const LocalTensor<T> | |||
| 57 | | count | 输入 | 参与计算的元素个数。 | | 57 | | count | 输入 | 参与计算的元素个数。 | |
| 58 | 58 | ||
| 59 | ## 数据类型 | 59 | ## 数据类型 |
| 60 | + | ||
| 60 | <!-- npu="950" id8 --> | 61 | <!-- npu="950" id8 --> |
| 61 | - 针对Ascend 950PR&950DT系列产品,T支持的数据类型为:half、float、bfloat16_t。 | 62 | - 针对Ascend 950PR&950DT系列产品,T支持的数据类型为:half、float、bfloat16_t。 |
| 62 | <!-- end id8 --> | 63 | <!-- end id8 --> |
| @@ -63,6 +63,7 @@ __simd_callee__ inline void Mins(S& dstReg, S& srcReg, U scalarValue, MaskReg& m | |||
| 63 | | mask | 输入 | 源操作数元素操作的有效指示,详细说明请参考[MaskReg](../register_data_types/MaskReg.md)。 | | 63 | | mask | 输入 | 源操作数元素操作的有效指示,详细说明请参考[MaskReg](../register_data_types/MaskReg.md)。 | |
| 64 | 64 | ||
| 65 | ## 数据类型 | 65 | ## 数据类型 |
| 66 | + | ||
| 66 | 目的操作数与源操作数的数据类型需要保持一致。支持的数据类型为:int8_t、uint8_t、int16_t、uint16_t、half、bfloat16_t、int32_t、uint32_t、float、int64_t、uint64_t。 | 67 | 目的操作数与源操作数的数据类型需要保持一致。支持的数据类型为:int8_t、uint8_t、int16_t、uint16_t、half、bfloat16_t、int32_t、uint32_t、float、int64_t、uint64_t。 |
| 67 | 68 | ||
| 68 | ## 返回值说明<a name="section640mcpsimp"></a> | 69 | ## 返回值说明<a name="section640mcpsimp"></a> |
| @@ -5,6 +5,7 @@ | |||
| 5 | Reg矢量计算架构中,Vector Function(VF)是实现高性能向量计算的核心载体。VF函数中可以包含最多四层嵌套循环,每层循环中还可以包含多个串行循环。VF循环对控制结构的支持有限,仅支持for循环和条件判断,不支持switch、do-while和while-do等其他控制结构。当VF函数中的循环满足Hardware Loop编码规范会被编译器优化为Hardware Loop,提升整体的编码性能,否则它的循环逻辑会由迭代变量和条件判断语句构成Software Loop,无法开启VF循环优化。 | 5 | Reg矢量计算架构中,Vector Function(VF)是实现高性能向量计算的核心载体。VF函数中可以包含最多四层嵌套循环,每层循环中还可以包含多个串行循环。VF循环对控制结构的支持有限,仅支持for循环和条件判断,不支持switch、do-while和while-do等其他控制结构。当VF函数中的循环满足Hardware Loop编码规范会被编译器优化为Hardware Loop,提升整体的编码性能,否则它的循环逻辑会由迭代变量和条件判断语句构成Software Loop,无法开启VF循环优化。 |
| 6 | 6 | ||
| 7 | ### Hardware Loop编码规范 | 7 | ### Hardware Loop编码规范 |
| 8 | + | ||
| 8 | - Hardware Loop最多能支持的嵌套层数为4层;支持串行的Hardware Loop循环。 | 9 | - Hardware Loop最多能支持的嵌套层数为4层;支持串行的Hardware Loop循环。 |
| 9 | - 迭代变量类型<br>VF内所有Loop的迭代变量必须是uint16_t类型。 | 10 | - 迭代变量类型<br>VF内所有Loop的迭代变量必须是uint16_t类型。 |
| 10 | - 起始值与步长<br>循环起始值从0开始。<br>每次迭代的步长必须是递增1。 | 11 | - 起始值与步长<br>循环起始值从0开始。<br>每次迭代的步长必须是递增1。 |
| @@ -13,6 +14,7 @@ Reg矢量计算架构中,Vector Function(VF)是实现高性能向量计算 | |||
| 13 | - 若要利用外层循环的计数作为循环边界,将外层循环计数器赋值给标量后作为内层循环边界。 | 14 | - 若要利用外层循环的计数作为循环边界,将外层循环计数器赋值给标量后作为内层循环边界。 |
| 14 | 15 | ||
| 15 | ## 指令双发优化 | 16 | ## 指令双发优化 |
| 17 | + | ||
| 16 | Reg矢量计算接口指令单双发的情况请参考[Reg矢量计算接口指令单双发汇总](../../../../appendix/reg_vector_compute_interface_instruction_single_dual_issue_summary.md)。 | 18 | Reg矢量计算接口指令单双发的情况请参考[Reg矢量计算接口指令单双发汇总](../../../../appendix/reg_vector_compute_interface_instruction_single_dual_issue_summary.md)。 |
| 17 | 19 | ||
| 18 | 指令双发优化的性能优化详细内容请参考[算子实践参考-指令双发优化](../../../../../guide/operator_practice/simd_operator_optimization/vector_compute/vf_optimization/dual_issue_optimization.md)。 | 20 | 指令双发优化的性能优化详细内容请参考[算子实践参考-指令双发优化](../../../../../guide/operator_practice/simd_operator_optimization/vector_compute/vf_optimization/dual_issue_optimization.md)。 |
| @@ -32,11 +34,13 @@ VF并不是写的越长,把所有运算都放在一个for循环内就好,需 | |||
| 32 | 如果循环内存在依赖关系过多的指令,指令无法并发执行,即无法启用双发特性。可以通过展开循环,提升指令双发能力,贴近硬件乱序执行的特性;减少指令因为寄存器资源未到位而产生的等待。 | 34 | 如果循环内存在依赖关系过多的指令,指令无法并发执行,即无法启用双发特性。可以通过展开循环,提升指令双发能力,贴近硬件乱序执行的特性;减少指令因为寄存器资源未到位而产生的等待。 |
| 33 | 35 | ||
| 34 | ## VF融合 | 36 | ## VF融合 |
| 37 | + | ||
| 35 | VF融合是将代码中多个VF函数融合成一个VF函数,有效提升性能。VF融合特性是编译器优化特性,通过编译选项--cce-simd-vf-fusion=true开启,VF自动融合会借助Loop Fuse算法,将VF转换成Loop形态,然后将控制流等价(Control-Flow-Equivalent)的VF进行融合,最后将VF进行还原。编译器首先会做融合前的合法性检查,判断两个VF是否等价,Main侧中间代码是否能在VF内执行以及融合后是否可产生正收益。如果满足VF融合条件,编译器会自动执行VF融合优化,为保证融合后的VF执行逻辑与语义与融合前一致,会在原来两个VF之间保守地插入同步指令,编译器还会尝试外提、合并融合后的VF中的指令,对VF代码进行优化。融合策略是能融尽融,用户按照符合融合的合法性检查的模式进行编码,可以增加VF融合的机会。用户也可以参考融合原理手动进行融合优化。 | 38 | VF融合是将代码中多个VF函数融合成一个VF函数,有效提升性能。VF融合特性是编译器优化特性,通过编译选项--cce-simd-vf-fusion=true开启,VF自动融合会借助Loop Fuse算法,将VF转换成Loop形态,然后将控制流等价(Control-Flow-Equivalent)的VF进行融合,最后将VF进行还原。编译器首先会做融合前的合法性检查,判断两个VF是否等价,Main侧中间代码是否能在VF内执行以及融合后是否可产生正收益。如果满足VF融合条件,编译器会自动执行VF融合优化,为保证融合后的VF执行逻辑与语义与融合前一致,会在原来两个VF之间保守地插入同步指令,编译器还会尝试外提、合并融合后的VF中的指令,对VF代码进行优化。融合策略是能融尽融,用户按照符合融合的合法性检查的模式进行编码,可以增加VF融合的机会。用户也可以参考融合原理手动进行融合优化。 |
| 36 | 39 | ||
| 37 | VF融合的性能优化详细内容请参考[算子实践参考-VF融合优化](../../../../../guide/operator_practice/simd_operator_optimization/vector_compute/vf_optimization/vf_fusion_optimization.md)。 | 40 | VF融合的性能优化详细内容请参考[算子实践参考-VF融合优化](../../../../../guide/operator_practice/simd_operator_optimization/vector_compute/vf_optimization/vf_fusion_optimization.md)。 |
| 38 | 41 | ||
| 39 | ## 数据搬运优化 | 42 | ## 数据搬运优化 |
| 43 | + | ||
| 40 | Reg矢量计算API提供了下表所示多种搬运指令,合理选择搬运接口以及利用接口能力进行优化。连续非对齐场景优化的性能优化详细内容请参考[算子实践参考-连续非对齐场景优化](../../../../../guide/operator_practice/simd_operator_optimization/vector_compute/vf_optimization/continuous_unaligned_optimization.md)。 | 44 | Reg矢量计算API提供了下表所示多种搬运指令,合理选择搬运接口以及利用接口能力进行优化。连续非对齐场景优化的性能优化详细内容请参考[算子实践参考-连续非对齐场景优化](../../../../../guide/operator_practice/simd_operator_optimization/vector_compute/vf_optimization/continuous_unaligned_optimization.md)。 |
| 41 | 45 | ||
| 42 | | 场景 | 描述 | | 46 | | 场景 | 描述 | |
| @@ -1,7 +1,9 @@ | |||
| 1 | # 概述 | 1 | # 概述 |
| 2 | + | ||
| 2 | Reg矢量计算API是面向Reg矢量计算架构开发的API,用户可以通过该API直接对芯片中涉及Vector计算的寄存器进行操作,实现更大的灵活性和更好的性能。Reg矢量计算API与Memory矢量计算API功能相似,但与Memory矢量计算API输入和输出数据必须为LocalTensor不同,Reg矢量计算API的输入或输出数据均为Reg矢量计算寄存器。对于计算类API,其功能是从给定的寄存器获取数据,进行计算,并将结果保存在给定的寄存器。对于搬运类API,其功能是实现Unified Buffer(UB)和寄存器的数据搬运。由此可见,Reg矢量计算API相较于Memory矢量计算API,将数据搬运和Reg计算过程交给用户自主控制,从而实现更大的开发自由度。 | 3 | Reg矢量计算API是面向Reg矢量计算架构开发的API,用户可以通过该API直接对芯片中涉及Vector计算的寄存器进行操作,实现更大的灵活性和更好的性能。Reg矢量计算API与Memory矢量计算API功能相似,但与Memory矢量计算API输入和输出数据必须为LocalTensor不同,Reg矢量计算API的输入或输出数据均为Reg矢量计算寄存器。对于计算类API,其功能是从给定的寄存器获取数据,进行计算,并将结果保存在给定的寄存器。对于搬运类API,其功能是实现Unified Buffer(UB)和寄存器的数据搬运。由此可见,Reg矢量计算API相较于Memory矢量计算API,将数据搬运和Reg计算过程交给用户自主控制,从而实现更大的开发自由度。 |
| 3 | 4 | ||
| 4 | ## 如何使用Reg矢量计算API | 5 | ## 如何使用Reg矢量计算API |
| 6 | + | ||
| 5 | 基于寄存器的编程模型是指将数据从LocalTensor通过Reg搬运指令(Reg数据搬入)加载到寄存器中,进行复杂的数学计算Compute后通过Reg搬运指令(Reg数据搬出)搬出到LocalTensor中,所有的计算逻辑均在寄存器中完成,从而减少LocalTensor间的数据搬运,大大提升了整体性能,具体流程如下所示: | 7 | 基于寄存器的编程模型是指将数据从LocalTensor通过Reg搬运指令(Reg数据搬入)加载到寄存器中,进行复杂的数学计算Compute后通过Reg搬运指令(Reg数据搬出)搬出到LocalTensor中,所有的计算逻辑均在寄存器中完成,从而减少LocalTensor间的数据搬运,大大提升了整体性能,具体流程如下所示: |
| 6 | 8 | ||
| 7 | **图1** Reg矢量计算 | 9 | **图1** Reg矢量计算 |
| @@ -36,6 +36,7 @@ MaskReg寄存器用于指示在计算过程中哪些元素参与计算,宽度 | |||
| 36 |  | 36 |  |
| 37 | 37 | ||
| 38 | ## 函数原型<a name="section620mcpsimp"></a> | 38 | ## 函数原型<a name="section620mcpsimp"></a> |
| 39 | + | ||
| 39 | - CreateMask接口 | 40 | - CreateMask接口 |
| 40 | ```cpp | 41 | ```cpp |
| 41 | template <typename T, MaskPattern mode = MaskPattern::ALL, const RegTrait& regTrait = RegTraitNumOne> | 42 | template <typename T, MaskPattern mode = MaskPattern::ALL, const RegTrait& regTrait = RegTraitNumOne> |
| @@ -267,6 +268,7 @@ __simd_callee__ inline void Add(U& dstReg, U& srcReg0, U& srcReg1, MaskReg& mask | |||
| 267 | ``` | 268 | ``` |
| 268 | 269 | ||
| 269 | <!-- npu="910b,A3,950" id8 --> | 270 | <!-- npu="910b,A3,950" id8 --> |
| 271 | + | ||
| 270 | ### NPU架构版本2201与NPU架构版本3510之间Mask机制对比 | 272 | ### NPU架构版本2201与NPU架构版本3510之间Mask机制对比 |
| 271 | 273 | ||
| 272 | 本节对比[NPU架构版本2201](../../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md)在Normal模式的逐bit计算中Mask机制,与[NPU架构版本3510](../../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md)基于Reg矢量计算中Mask机制的差异。 | 274 | 本节对比[NPU架构版本2201](../../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md)在Normal模式的逐bit计算中Mask机制,与[NPU架构版本3510](../../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md)基于Reg矢量计算中Mask机制的差异。 |
| @@ -289,6 +289,7 @@ result[i][7 :0] = saturation(tmp[7 : 0]) according to control bit; | |||
| 289 | ``` | 289 | ``` |
| 290 | 290 | ||
| 291 | ### half转hifloat8_t转换规则 | 291 | ### half转hifloat8_t转换规则 |
| 292 | + | ||
| 292 | ``` | 293 | ``` |
| 293 | tmp2[15 : 0] = f16_src_data[i][15 : 0]; | 294 | tmp2[15 : 0] = f16_src_data[i][15 : 0]; |
| 294 | Ev = tmp2[14 : 10] - 5'b01111, thr = {tmp2[0], 1’b1}; | 295 | Ev = tmp2[14 : 10] - 5'b01111, thr = {tmp2[0], 1’b1}; |
| @@ -26,6 +26,7 @@ | |||
| 26 | <!-- @ref: asc-devkit/res/docs/zh/api/SIMD-API/basic_api/scalar_compute/Nop_res.md#id1 --> | 26 | <!-- @ref: asc-devkit/res/docs/zh/api/SIMD-API/basic_api/scalar_compute/Nop_res.md#id1 --> |
| 27 | 27 | ||
| 28 | ## 功能说明 | 28 | ## 功能说明 |
| 29 | + | ||
| 29 | 头文件路径为:`"basic_api/kernel_operator_utils_intf.h"`。 | 30 | 头文件路径为:`"basic_api/kernel_operator_utils_intf.h"`。 |
| 30 | 31 | ||
| 31 | 用户输入延迟的个数,实现延迟若干个cycle。 | 32 | 用户输入延迟的个数,实现延迟若干个cycle。 |
| @@ -80,6 +80,7 @@ | |||
| 80 | - 在**3510架构**下占用模式4的flagId为1、17(AIC:1、17;AIV:1)。参见[DataCopy(GMToL1连续数据搬运)](../../cube_compute_ISASI/cube_compute_load/DataCopy_GMToL1_continuous.md)。 | 80 | - 在**3510架构**下占用模式4的flagId为1、17(AIC:1、17;AIV:1)。参见[DataCopy(GMToL1连续数据搬运)](../../cube_compute_ISASI/cube_compute_load/DataCopy_GMToL1_continuous.md)。 |
| 81 | 81 | ||
| 82 | ## 各个核间同步控制实现原理<a id="sync_control_mode"></a> | 82 | ## 各个核间同步控制实现原理<a id="sync_control_mode"></a> |
| 83 | + | ||
| 83 | 如图1所示,本章节将配合时序图介绍CrossCoreSetFlag和CrossCoreWaitFlag配合使用时支持的四种同步控制模式各自实现的原理。 | 84 | 如图1所示,本章节将配合时序图介绍CrossCoreSetFlag和CrossCoreWaitFlag配合使用时支持的四种同步控制模式各自实现的原理。 |
| 84 | 85 | ||
| 85 | - 模式0:AI Core核间的同步控制。对于AIC全核场景,同步所有的AIC核,直到所有的AIC核都执行到CrossCoreSetFlag时,CrossCoreWaitFlag后续的全部流水或者由模板参数pipe指定的流水(与NPU架构有关)中的指令才会执行;对于AIV全核场景,同步所有的AIV核,直到所有的AIV核都执行到CrossCoreSetFlag时,CrossCoreWaitFlag后续的全部流水或者由模板参数pipe指定的流水(与NPU架构有关)中的指令才会执行。 | 86 | - 模式0:AI Core核间的同步控制。对于AIC全核场景,同步所有的AIC核,直到所有的AIC核都执行到CrossCoreSetFlag时,CrossCoreWaitFlag后续的全部流水或者由模板参数pipe指定的流水(与NPU架构有关)中的指令才会执行;对于AIV全核场景,同步所有的AIV核,直到所有的AIV核都执行到CrossCoreSetFlag时,CrossCoreWaitFlag后续的全部流水或者由模板参数pipe指定的流水(与NPU架构有关)中的指令才会执行。 |
| @@ -55,6 +55,7 @@ PIPE_S | |||
| 55 | - 本接口仅对矩阵乘加输入数据类型为`fp8_e4m3fn_t`×`fp8_e4m3fn_t`的场景生效,其他FP8数据类型组合(`fp8_e4m3fn_t`×`fp8_e5m2_t`、`fp8_e5m2_t`×`fp8_e4m3fn_t`、`fp8_e5m2_t`×`fp8_e5m2_t`)不支持FP8与HiF8模式选择,调用本接口不产生实际作用。 | 55 | - 本接口仅对矩阵乘加输入数据类型为`fp8_e4m3fn_t`×`fp8_e4m3fn_t`的场景生效,其他FP8数据类型组合(`fp8_e4m3fn_t`×`fp8_e5m2_t`、`fp8_e5m2_t`×`fp8_e4m3fn_t`、`fp8_e5m2_t`×`fp8_e5m2_t`)不支持FP8与HiF8模式选择,调用本接口不产生实际作用。 |
| 56 | 56 | ||
| 57 | <!-- npu="950" id8 --> | 57 | <!-- npu="950" id8 --> |
| 58 | + | ||
| 58 | ## 调用示例 | 59 | ## 调用示例 |
| 59 | 60 | ||
| 60 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[\_\_NPU\_ARCH\_\_](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 | 61 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[\_\_NPU\_ARCH\_\_](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 |
| @@ -67,6 +67,7 @@ $$ | |||
| 67 | ## 函数原型 | 67 | ## 函数原型 |
| 68 | 68 | ||
| 69 | <!-- npu="950" id12 --> | 69 | <!-- npu="950" id12 --> |
| 70 | + | ||
| 70 | ### 函数原型([NPU架构版本3510](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md)) | 71 | ### 函数原型([NPU架构版本3510](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md)) |
| 71 | 72 | ||
| 72 | **占位符形式:** | 73 | **占位符形式:** |
| @@ -143,6 +144,7 @@ __aicore__ inline void asc_mmad(__cc__ float* c_matrix, | |||
| 143 | <!-- end id12 --> | 144 | <!-- end id12 --> |
| 144 | 145 | ||
| 145 | <!-- npu="A3,910b" id13 --> | 146 | <!-- npu="A3,910b" id13 --> |
| 147 | + | ||
| 146 | ### 函数原型([NPU架构版本2201](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md)) | 148 | ### 函数原型([NPU架构版本2201](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md)) |
| 147 | 149 | ||
| 148 | **占位符形式:** | 150 | **占位符形式:** |
| @@ -1,6 +1,7 @@ | |||
| 1 | # 辅助矩阵分形格式详解 | 1 | # 辅助矩阵分形格式详解 |
| 2 | 2 | ||
| 3 | <!-- npu="950" id1 --> | 3 | <!-- npu="950" id1 --> |
| 4 | + | ||
| 4 | ## MX系数矩阵 | 5 | ## MX系数矩阵 |
| 5 | 6 | ||
| 6 | 针对Ascend 950PR&950DT系列产品产品: | 7 | 针对Ascend 950PR&950DT系列产品产品: |
| @@ -71,6 +72,7 @@ MX矩阵乘法为带有量化系数X的矩阵乘法,即左矩阵和右矩阵 | |||
| 71 | <!-- end id1 --> | 72 | <!-- end id1 --> |
| 72 | 73 | ||
| 73 | <!-- npu="A3,910b" id2 --> | 74 | <!-- npu="A3,910b" id2 --> |
| 75 | + | ||
| 74 | ## 4选2稀疏索引矩阵 | 76 | ## 4选2稀疏索引矩阵 |
| 75 | 77 | ||
| 76 | 针对Atlas A2训练系列产品/Atlas A2推理系列产品和Atlas A3训练系列产品/Atlas A3推理系列产品: | 78 | 针对Atlas A2训练系列产品/Atlas A2推理系列产品和Atlas A3训练系列产品/Atlas A3推理系列产品: |
Mdocs/zh/api/SIMD-API/c_api/cube_compute/cube_compute_fractal_intro/key_fractal_format_details.md+1-0
| @@ -61,6 +61,7 @@ | |||
| 61 | <!-- end id5 --> | 61 | <!-- end id5 --> |
| 62 | 62 | ||
| 63 | <!-- npu="910b,A3" id6 --> | 63 | <!-- npu="910b,A3" id6 --> |
| 64 | + | ||
| 64 | ## Zz格式(FRACTAL_Zz) | 65 | ## Zz格式(FRACTAL_Zz) |
| 65 | 66 | ||
| 66 | - **定义:** 大Z外部row major(行主序)+ 小z内部row major(行主序),见下图。 | 67 | - **定义:** 大Z外部row major(行主序)+ 小z内部row major(行主序),见下图。 |
| @@ -72,6 +72,7 @@ PIPE_MTE2 | |||
| 72 | - 操作数地址重叠约束请参考[通用地址重叠约束](../general_description_and_constraints.md#通用地址重叠约束)。 | 72 | - 操作数地址重叠约束请参考[通用地址重叠约束](../general_description_and_constraints.md#通用地址重叠约束)。 |
| 73 | 73 | ||
| 74 | ## 调用示例 | 74 | ## 调用示例 |
| 75 | + | ||
| 75 | ```cpp | 76 | ```cpp |
| 76 | __ca__ half dst[256]; | 77 | __ca__ half dst[256]; |
| 77 | // src表示源操作数的起始地址 | 78 | // src表示源操作数的起始地址 |
| @@ -85,6 +85,7 @@ PIPE_S | |||
| 85 | - 本接口的配置会持续生效,直至再次调用本接口覆盖。不同搬出任务使用的配置不同时,需在对应搬出接口执行前重新配置,每次调用均会同时覆盖三个参数。 | 85 | - 本接口的配置会持续生效,直至再次调用本接口覆盖。不同搬出任务使用的配置不同时,需在对应搬出接口执行前重新配置,每次调用均会同时覆盖三个参数。 |
| 86 | 86 | ||
| 87 | <!-- npu="950" id12 --> | 87 | <!-- npu="950" id12 --> |
| 88 | + | ||
| 88 | ## 调用示例 | 89 | ## 调用示例 |
| 89 | 90 | ||
| 90 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[\_\_NPU\_ARCH\_\_](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 | 91 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[\_\_NPU\_ARCH\_\_](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 |
| @@ -62,6 +62,7 @@ PIPE_S | |||
| 62 | - 调用后配置会持续生效,直至再次调用本接口覆盖,不同搬出任务使用的系数不同时,需在对应搬出接口执行前重新配置。 | 62 | - 调用后配置会持续生效,直至再次调用本接口覆盖,不同搬出任务使用的系数不同时,需在对应搬出接口执行前重新配置。 |
| 63 | 63 | ||
| 64 | <!-- npu="950" id8 --> | 64 | <!-- npu="950" id8 --> |
| 65 | + | ||
| 65 | ## 调用示例 | 66 | ## 调用示例 |
| 66 | 67 | ||
| 67 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[\_\_NPU\_ARCH\_\_](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 | 68 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[\_\_NPU\_ARCH\_\_](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 |
| @@ -62,6 +62,7 @@ PIPE_S | |||
| 62 | - 调用后配置会持续生效,直至再次调用本接口覆盖,不同搬出任务使用的系数不同时,需在对应搬出接口执行前重新配置。 | 62 | - 调用后配置会持续生效,直至再次调用本接口覆盖,不同搬出任务使用的系数不同时,需在对应搬出接口执行前重新配置。 |
| 63 | 63 | ||
| 64 | <!-- npu="950" id8 --> | 64 | <!-- npu="950" id8 --> |
| 65 | + | ||
| 65 | ## 调用示例 | 66 | ## 调用示例 |
| 66 | 67 | ||
| 67 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[\_\_NPU\_ARCH\_\_](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 | 68 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[\_\_NPU\_ARCH\_\_](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 |
| @@ -75,6 +75,7 @@ PIPE_S | |||
| 75 | - 调用后配置会持续生效,直至再次调用本接口覆盖,不同3D搬运任务使用的配置不同时,需在对应搬运接口执行前重新配置。 | 75 | - 调用后配置会持续生效,直至再次调用本接口覆盖,不同3D搬运任务使用的配置不同时,需在对应搬运接口执行前重新配置。 |
| 76 | 76 | ||
| 77 | <!-- npu="950" id8 --> | 77 | <!-- npu="950" id8 --> |
| 78 | + | ||
| 78 | ## 调用示例 | 79 | ## 调用示例 |
| 79 | 80 | ||
| 80 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[`__NPU_ARCH__`](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 | 81 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[`__NPU_ARCH__`](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 |
| @@ -76,6 +76,7 @@ PIPE_S | |||
| 76 | - 调用后配置会持续生效,直至再次调用本接口覆盖,不同3D搬运任务使用的配置不同时,需在对应搬运接口执行前重新配置。 | 76 | - 调用后配置会持续生效,直至再次调用本接口覆盖,不同3D搬运任务使用的配置不同时,需在对应搬运接口执行前重新配置。 |
| 77 | 77 | ||
| 78 | <!-- npu="950" id8 --> | 78 | <!-- npu="950" id8 --> |
| 79 | + | ||
| 79 | ## 调用示例 | 80 | ## 调用示例 |
| 80 | 81 | ||
| 81 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[`__NPU_ARCH__`](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 | 82 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[`__NPU_ARCH__`](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 |
| @@ -74,6 +74,7 @@ PIPE_S | |||
| 74 | - 调用后配置会持续生效,直至再次调用本接口覆盖,不同3D搬运任务使用的配置不同时,需在对应搬运接口执行前重新配置。 | 74 | - 调用后配置会持续生效,直至再次调用本接口覆盖,不同3D搬运任务使用的配置不同时,需在对应搬运接口执行前重新配置。 |
| 75 | 75 | ||
| 76 | <!-- npu="950" id8 --> | 76 | <!-- npu="950" id8 --> |
| 77 | + | ||
| 77 | ## 调用示例 | 78 | ## 调用示例 |
| 78 | 79 | ||
| 79 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[`__NPU_ARCH__`](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 | 80 | 将代码保存为`example.asc`后,可通过`bisheng`命令编译运行,其中`--npu-arch`参数需根据实际产品型号指定对应的NPU架构,具体产品与NPU架构的映射关系请参考[`__NPU_ARCH__`](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md#npu-arch)。 |
| @@ -69,6 +69,7 @@ PIPE_S | |||
| 69 | - 调用后配置会持续生效,直至再次调用本接口覆盖,不同3D搬运任务使用的配置不同时,需在对应搬运接口执行前重新配置。 | 69 | - 调用后配置会持续生效,直至再次调用本接口覆盖,不同3D搬运任务使用的配置不同时,需在对应搬运接口执行前重新配置。 |
| 70 | 70 | ||
| 71 | <!-- npu="950" id8 --> | 71 | <!-- npu="950" id8 --> |
| 72 | + | ||
| 72 | ## 调用示例 | 73 | ## 调用示例 |
| 73 | 74 | ||
| 74 | 以下示例使用`asc_copy_l12l0b`将2×2、16通道的全零Feature Map扩展为带一圈padding的4×4矩阵,并自动转置写入L0B Buffer。B侧padding值设置为2,`f_matrix_ctrl`设置为`true`。使用全1的L0A矩阵进行MMAD后,每个输出累加4×4区域中的12个padding位置,期望值为`12 × 2 = 24`。 | 75 | 以下示例使用`asc_copy_l12l0b`将2×2、16通道的全零Feature Map扩展为带一圈padding的4×4矩阵,并自动转置写入L0B Buffer。B侧padding值设置为2,`f_matrix_ctrl`设置为`true`。使用全1的L0A矩阵进行MMAD后,每个输出累加4×4区域中的12个padding位置,期望值为`12 × 2 = 24`。 |
| @@ -72,6 +72,7 @@ PIPE_S | |||
| 72 | - 调用后配置会持续生效,直至再次调用本接口覆盖,不同3D搬运任务使用的配置不同时,需在对应搬运接口执行前重新配置。 | 72 | - 调用后配置会持续生效,直至再次调用本接口覆盖,不同3D搬运任务使用的配置不同时,需在对应搬运接口执行前重新配置。 |
| 73 | 73 | ||
| 74 | <!-- npu="950" id8 --> | 74 | <!-- npu="950" id8 --> |
| 75 | + | ||
| 75 | ## 调用示例 | 76 | ## 调用示例 |
| 76 | 77 | ||
| 77 | `asc_set_l3d_rpt_b`需要调用者自行拼装64位配置。相同功能推荐使用参数化接口[asc_set_l13d_rpt_b](asc_set_l13d_rpt_b.md),以下示例使用该接口配置右矩阵的repeat参数。 | 78 | `asc_set_l3d_rpt_b`需要调用者自行拼装64位配置。相同功能推荐使用参数化接口[asc_set_l13d_rpt_b](asc_set_l13d_rpt_b.md),以下示例使用该接口配置右矩阵的repeat参数。 |
| @@ -34,6 +34,7 @@ asc_copy_l12l0b_sparse主要用于搬运以512Byte为单位存放的压缩权重 | |||
| 34 | 矩阵计算过程中,常用分形支持总结如下表: | 34 | 矩阵计算过程中,常用分形支持总结如下表: |
| 35 | 35 | ||
| 36 | <!-- npu="910b,A3" id7 --> | 36 | <!-- npu="910b,A3" id7 --> |
| 37 | + | ||
| 37 | ### 针对Atlas A2训练系列产品/Atlas A2推理系列产品和Atlas A3训练系列产品/Atlas A3推理系列产品 | 38 | ### 针对Atlas A2训练系列产品/Atlas A2推理系列产品和Atlas A3训练系列产品/Atlas A3推理系列产品 |
| 38 | 39 | ||
| 39 | 常用分形支持情况如下,供开发者参考: | 40 | 常用分形支持情况如下,供开发者参考: |
| @@ -119,6 +120,7 @@ asc_copy_l12l0b_sparse主要用于搬运以512Byte为单位存放的压缩权重 | |||
| 119 | <!-- end id7 --> | 120 | <!-- end id7 --> |
| 120 | 121 | ||
| 121 | <!-- npu="950" id8 --> | 122 | <!-- npu="950" id8 --> |
| 123 | + | ||
| 122 | ### 针对Ascend 950PR&950DT系列产品 | 124 | ### 针对Ascend 950PR&950DT系列产品 |
| 123 | 125 | ||
| 124 | 数据搬运(GM-\>L1 Buffer)支持使能随路进行DN到Nz转换,一定会改变分形排布。 | 126 | 数据搬运(GM-\>L1 Buffer)支持使能随路进行DN到Nz转换,一定会改变分形排布。 |
| @@ -48,6 +48,7 @@ | |||
| 48 | <!-- end id2 --> | 48 | <!-- end id2 --> |
| 49 | 49 | ||
| 50 | <!-- npu="950" id5 --> | 50 | <!-- npu="950" id5 --> |
| 51 | + | ||
| 51 | ## UB->L1 Buffer的接口分类与使用场景 | 52 | ## UB->L1 Buffer的接口分类与使用场景 |
| 52 | 53 | ||
| 53 | **表4** UB->L1 Buffer接口 | 54 | **表4** UB->L1 Buffer接口 |
| @@ -1,4 +1,5 @@ | |||
| 1 | # asc_clear_ar_spr(废弃) | 1 | # asc_clear_ar_spr(废弃) |
| 2 | + | ||
| 2 | ## 产品支持情况 | 3 | ## 产品支持情况 |
| 3 | 4 | ||
| 4 | <!-- npu="950" id1 --> | 5 | <!-- npu="950" id1 --> |
| @@ -74,6 +74,7 @@ PIPE_MTE2 | |||
| 74 | - 操作数地址重叠约束请参考[通用地址重叠约束](../general_description_and_constraints.md#通用地址重叠约束)。 | 74 | - 操作数地址重叠约束请参考[通用地址重叠约束](../general_description_and_constraints.md#通用地址重叠约束)。 |
| 75 | 75 | ||
| 76 | ## 调用示例 | 76 | ## 调用示例 |
| 77 | + | ||
| 77 | ```cpp | 78 | ```cpp |
| 78 | __ca__ half dst[256]; | 79 | __ca__ half dst[256]; |
| 79 | // src表示源操作数的起始地址 | 80 | // src表示源操作数的起始地址 |
| @@ -63,6 +63,7 @@ | |||
| 63 | PIPE_V | 63 | PIPE_V |
| 64 | 64 | ||
| 65 | ## 约束说明 | 65 | ## 约束说明 |
| 66 | + | ||
| 66 | - src_offset取值应保证src元素类型位宽对齐。 | 67 | - src_offset取值应保证src元素类型位宽对齐。 |
| 67 | - src加上src_offset偏移后的地址不能超出Unified Buffer(UB)大小数据的范围。 | 68 | - src加上src_offset偏移后的地址不能超出Unified Buffer(UB)大小数据的范围。 |
| 68 | - dst、src的起始地址需要32字节对齐。 | 69 | - dst、src的起始地址需要32字节对齐。 |
| @@ -1,4 +1,5 @@ | |||
| 1 | # asc_int322uint8(废弃) | 1 | # asc_int322uint8(废弃) |
| 2 | + | ||
| 2 | ## 产品支持情况 | 3 | ## 产品支持情况 |
| 3 | 4 | ||
| 4 | <!-- npu="950" id1 --> | 5 | <!-- npu="950" id1 --> |
| @@ -48,6 +48,7 @@ __aicore__ inline void asc_max_sync(__ubuf__ float* dst, __ubuf__ float* src0, _ | |||
| 48 | ``` | 48 | ``` |
| 49 | 49 | ||
| 50 | ## 参数说明 | 50 | ## 参数说明 |
| 51 | + | ||
| 51 | **表1** 参数说明 | 52 | **表1** 参数说明 |
| 52 | 53 | ||
| 53 | | 参数名 | 输入/输出 | 描述 | | 54 | | 参数名 | 输入/输出 | 描述 | |
| @@ -82,6 +82,7 @@ K0的取值为`32B / sizeof(dtype)`,`dtype`为矩阵的数据类型。当数 | |||
| 82 | ## 函数原型 | 82 | ## 函数原型 |
| 83 | 83 | ||
| 84 | <!-- npu="950" id12 --> | 84 | <!-- npu="950" id12 --> |
| 85 | + | ||
| 85 | ### 函数原型([NPU架构版本3510](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md)) | 86 | ### 函数原型([NPU架构版本3510](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md)) |
| 86 | 87 | ||
| 87 | **占位符形式:** | 88 | **占位符形式:** |
| @@ -145,6 +146,7 @@ __aicore__ inline void asc_mmad(__cc__ float* c_matrix, | |||
| 145 | <!-- end id12 --> | 146 | <!-- end id12 --> |
| 146 | 147 | ||
| 147 | <!-- npu="A3,910b" id20 --> | 148 | <!-- npu="A3,910b" id20 --> |
| 149 | + | ||
| 148 | ### 函数原型([NPU架构版本2201](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md)) | 150 | ### 函数原型([NPU架构版本2201](../../../../guide/programming_guide/language_extension/simd_builtin_keywords.md)) |
| 149 | 151 | ||
| 150 | - `asc_mmad`及`asc_mmad_sync`: | 152 | - `asc_mmad`及`asc_mmad_sync`: |
| @@ -1,4 +1,5 @@ | |||
| 1 | # asc_set_l0c2gm_config(废弃) | 1 | # asc_set_l0c2gm_config(废弃) |
| 2 | + | ||
| 2 | ## 产品支持情况 | 3 | ## 产品支持情况 |
| 3 | 4 | ||
| 4 | <!-- npu="950" id1 --> | 5 | <!-- npu="950" id1 --> |
| @@ -46,6 +47,7 @@ __aicore__ inline void asc_set_l0c2gm_config(uint64_t relu_pre, uint64_t quant_p | |||
| 46 | | relu_pre | 输入 | ReLU操作前矢量的起始地址。| | 47 | | relu_pre | 输入 | ReLU操作前矢量的起始地址。| |
| 47 | | quant_pre | 输入 | 量化操作前矢量的起始地址。| | 48 | | quant_pre | 输入 | 量化操作前矢量的起始地址。| |
| 48 | | enable_unit_flag | 输入 | 是否启用unit_flag。unit_flag是一种矩阵计算指令和矩阵搬运指令细粒度的并行,开启该功能后,硬件每计算完一个分形,计算结果就会被搬出,该功能不适用于L0C Buffer累加的场景。| | 49 | | enable_unit_flag | 输入 | 是否启用unit_flag。unit_flag是一种矩阵计算指令和矩阵搬运指令细粒度的并行,开启该功能后,硬件每计算完一个分形,计算结果就会被搬出,该功能不适用于L0C Buffer累加的场景。| |
| 50 | + | ||
| 49 | ## 返回值说明 | 51 | ## 返回值说明 |
| 50 | 52 | ||
| 51 | 无 | 53 | 无 |
| @@ -72,6 +72,7 @@ PIPE_S | |||
| 72 | 量化参数不能为inf/nan和非规格化数。 | 72 | 量化参数不能为inf/nan和非规格化数。 |
| 73 | 73 | ||
| 74 | ## 调用示例 | 74 | ## 调用示例 |
| 75 | + | ||
| 75 | ```cpp | 76 | ```cpp |
| 76 | const uint64_t MASK_8_0 = 0x1FF; | 77 | const uint64_t MASK_8_0 = 0x1FF; |
| 77 | const uint64_t MASK_BIT9 = 0x200; | 78 | const uint64_t MASK_BIT9 = 0x200; |
| @@ -67,6 +67,7 @@ PIPE_S | |||
| 67 | 无 | 67 | 无 |
| 68 | 68 | ||
| 69 | ## 调用示例 | 69 | ## 调用示例 |
| 70 | + | ||
| 70 | ```cpp | 71 | ```cpp |
| 71 | uint64_t config = 0; | 72 | uint64_t config = 0; |
| 72 | asc_set_l12l0_padding_val(config); | 73 | asc_set_l12l0_padding_val(config); |
| @@ -62,6 +62,7 @@ $$ | |||
| 62 | PIPE_V | 62 | PIPE_V |
| 63 | 63 | ||
| 64 | ## 约束说明 | 64 | ## 约束说明 |
| 65 | + | ||
| 65 | - src只支持设置为正数。 | 66 | - src只支持设置为正数。 |
| 66 | - 操作数地址重叠约束请参考[通用地址重叠约束](../general_description_and_constraints.md#通用地址重叠约束)。 | 67 | - 操作数地址重叠约束请参考[通用地址重叠约束](../general_description_and_constraints.md#通用地址重叠约束)。 |
| 67 | - dst、src的起始地址需要32字节对齐。 | 68 | - dst、src的起始地址需要32字节对齐。 |
| @@ -5,6 +5,7 @@ | |||
| 5 | Reg矢量计算架构中,Vector Function(VF)是实现高性能向量计算的核心载体。VF函数中可以包含最多四层嵌套循环,每层循环中还可以包含多个串行循环。VF循环对控制结构的支持有限,仅支持for循环和条件判断,不支持switch、do-while和while-do等其他控制结构。当VF函数中的循环满足Hardware Loop编码规范会被编译器优化为Hardware Loop,提升整体的编码性能,否则它的循环逻辑会由迭代变量和条件判断语句构成Software Loop,无法开启VF循环优化。 | 5 | Reg矢量计算架构中,Vector Function(VF)是实现高性能向量计算的核心载体。VF函数中可以包含最多四层嵌套循环,每层循环中还可以包含多个串行循环。VF循环对控制结构的支持有限,仅支持for循环和条件判断,不支持switch、do-while和while-do等其他控制结构。当VF函数中的循环满足Hardware Loop编码规范会被编译器优化为Hardware Loop,提升整体的编码性能,否则它的循环逻辑会由迭代变量和条件判断语句构成Software Loop,无法开启VF循环优化。 |
| 6 | 6 | ||
| 7 | ### Hardware Loop编码规范 | 7 | ### Hardware Loop编码规范 |
| 8 | + | ||
| 8 | - Hardware Loop最多能支持的嵌套层数为4层;支持串行的Hardware Loop循环。 | 9 | - Hardware Loop最多能支持的嵌套层数为4层;支持串行的Hardware Loop循环。 |
| 9 | - 迭代变量类型<br>VF内所有Loop的迭代变量必须是uint16_t类型。 | 10 | - 迭代变量类型<br>VF内所有Loop的迭代变量必须是uint16_t类型。 |
| 10 | - 起始值与步长<br>循环起始值从0开始。<br>每次迭代的步长必须是递增1。 | 11 | - 起始值与步长<br>循环起始值从0开始。<br>每次迭代的步长必须是递增1。 |
| @@ -13,6 +14,7 @@ Reg矢量计算架构中,Vector Function(VF)是实现高性能向量计算 | |||
| 13 | - 若要利用外层循环的计数作为循环边界,将外层循环计数器赋值给标量后作为内层循环边界。 | 14 | - 若要利用外层循环的计数作为循环边界,将外层循环计数器赋值给标量后作为内层循环边界。 |
| 14 | 15 | ||
| 15 | ## 指令双发优化 | 16 | ## 指令双发优化 |
| 17 | + | ||
| 16 | Reg矢量计算接口指令单双发的情况请参考[Reg矢量计算接口指令单双发汇总](../../../appendix/reg_vector_compute_interface_instruction_single_dual_issue_summary.md)。 | 18 | Reg矢量计算接口指令单双发的情况请参考[Reg矢量计算接口指令单双发汇总](../../../appendix/reg_vector_compute_interface_instruction_single_dual_issue_summary.md)。 |
| 17 | 19 | ||
| 18 | 指令双发优化的性能优化详细内容请参考[算子实践参考-指令双发优化](../../../../guide/operator_practice/simd_operator_optimization/vector_compute/vf_optimization/dual_issue_optimization.md)。 | 20 | 指令双发优化的性能优化详细内容请参考[算子实践参考-指令双发优化](../../../../guide/operator_practice/simd_operator_optimization/vector_compute/vf_optimization/dual_issue_optimization.md)。 |
| @@ -32,6 +34,7 @@ VF并不是写的越长,把所有运算都放在一个for循环内就好,需 | |||
| 32 | 如果循环内存在依赖关系过多的指令,指令无法并发执行,即无法启用双发特性。可以通过展开循环,提升指令双发能力,贴近硬件乱序执行的特性;减少指令因为寄存器资源未到位而产生的等待。 | 34 | 如果循环内存在依赖关系过多的指令,指令无法并发执行,即无法启用双发特性。可以通过展开循环,提升指令双发能力,贴近硬件乱序执行的特性;减少指令因为寄存器资源未到位而产生的等待。 |
| 33 | 35 | ||
| 34 | ## VF融合 | 36 | ## VF融合 |
| 37 | + | ||
| 35 | VF融合是将代码中多个VF函数融合成一个VF函数,有效提升性能。VF融合特性是编译器优化特性,通过编译选项--cce-simd-vf-fusion=true开启,VF自动融合会借助Loop Fuse算法,将VF转换成Loop形态,然后将控制流等价(Control-Flow-Equivalent)的VF进行融合,最后将VF进行还原。编译器首先会做融合前的合法性检查,判断两个VF是否等价,Main侧中间代码是否能在VF内执行以及融合后是否可产生正收益。如果满足VF融合条件,编译器会自动执行VF融合优化,为保证融合后的VF执行逻辑与语义与融合前一致,会在原来两个VF之间保守地插入同步指令,编译器还会尝试外提、合并融合后的VF中的指令,对VF代码进行优化。融合策略是能融尽融,用户按照符合融合的合法性检查的模式进行编码,可以增加VF融合的机会。用户也可以参考融合原理手动进行融合优化。 | 38 | VF融合是将代码中多个VF函数融合成一个VF函数,有效提升性能。VF融合特性是编译器优化特性,通过编译选项--cce-simd-vf-fusion=true开启,VF自动融合会借助Loop Fuse算法,将VF转换成Loop形态,然后将控制流等价(Control-Flow-Equivalent)的VF进行融合,最后将VF进行还原。编译器首先会做融合前的合法性检查,判断两个VF是否等价,Main侧中间代码是否能在VF内执行以及融合后是否可产生正收益。如果满足VF融合条件,编译器会自动执行VF融合优化,为保证融合后的VF执行逻辑与语义与融合前一致,会在原来两个VF之间保守地插入同步指令,编译器还会尝试外提、合并融合后的VF中的指令,对VF代码进行优化。融合策略是能融尽融,用户按照符合融合的合法性检查的模式进行编码,可以增加VF融合的机会。用户也可以参考融合原理手动进行融合优化。 |
| 36 | 39 | ||
| 37 | VF融合的性能优化详细内容请参考[算子实践参考-VF融合优化](../../../../guide/operator_practice/simd_operator_optimization/vector_compute/vf_optimization/vf_fusion_optimization.md)。 | 40 | VF融合的性能优化详细内容请参考[算子实践参考-VF融合优化](../../../../guide/operator_practice/simd_operator_optimization/vector_compute/vf_optimization/vf_fusion_optimization.md)。 |
| @@ -1,7 +1,9 @@ | |||
| 1 | # 概述 | 1 | # 概述 |
| 2 | + | ||
| 2 | Reg矢量计算C API提供面向Reg矢量计算架构的寄存器级矢量计算能力,用户可以通过该API直接对芯片中涉及Vector计算的寄存器进行操作,实现更大的灵活性和更好的性能。Reg矢量计算C API与Memory矢量计算C API功能相似,但与Memory矢量计算C API的输入和输出数据通常位于Unified Buffer(UB)不同,Reg矢量计算C API的输入或输出数据可使用矢量数据寄存器`vector_<dtype>`(`dtype`为占位符,表示`half`、`float`等C API支持的数据类型)和掩码寄存器`vector_bool`。对于计算类API,其功能是从给定的寄存器获取数据,进行计算,并将结果保存在给定的寄存器。对于搬运类API,其功能是实现UB和寄存器的数据搬运。由此可见,Reg矢量计算C API相较于Memory矢量计算C API,将数据搬运和Reg计算过程交给用户自主控制,从而实现更大的开发自由度。 | 3 | Reg矢量计算C API提供面向Reg矢量计算架构的寄存器级矢量计算能力,用户可以通过该API直接对芯片中涉及Vector计算的寄存器进行操作,实现更大的灵活性和更好的性能。Reg矢量计算C API与Memory矢量计算C API功能相似,但与Memory矢量计算C API的输入和输出数据通常位于Unified Buffer(UB)不同,Reg矢量计算C API的输入或输出数据可使用矢量数据寄存器`vector_<dtype>`(`dtype`为占位符,表示`half`、`float`等C API支持的数据类型)和掩码寄存器`vector_bool`。对于计算类API,其功能是从给定的寄存器获取数据,进行计算,并将结果保存在给定的寄存器。对于搬运类API,其功能是实现UB和寄存器的数据搬运。由此可见,Reg矢量计算C API相较于Memory矢量计算C API,将数据搬运和Reg计算过程交给用户自主控制,从而实现更大的开发自由度。 |
| 3 | 4 | ||
| 4 | ## 如何使用Reg矢量计算API | 5 | ## 如何使用Reg矢量计算API |
| 6 | + | ||
| 5 | 基于寄存器的编程模型是指将数据从UB通过Reg搬运指令(Reg数据搬入)加载到寄存器中,进行复杂的数学计算后通过Reg搬运指令(Reg数据搬出)搬出到UB中,所有的计算逻辑均在寄存器中完成,从而减少UB中间数据的反复读写,大大提升整体性能,具体流程如下所示: | 7 | 基于寄存器的编程模型是指将数据从UB通过Reg搬运指令(Reg数据搬入)加载到寄存器中,进行复杂的数学计算后通过Reg搬运指令(Reg数据搬出)搬出到UB中,所有的计算逻辑均在寄存器中完成,从而减少UB中间数据的反复读写,大大提升整体性能,具体流程如下所示: |
| 6 | 8 | ||
| 7 | **图1** Reg矢量计算 | 9 | **图1** Reg矢量计算 |
| @@ -110,6 +110,7 @@ __simd_callee__ inline void asc_sub(vector_bool& carry, | |||
| 110 | vector_int32_t src1, | 110 | vector_int32_t src1, |
| 111 | vector_bool mask) | 111 | vector_bool mask) |
| 112 | ``` | 112 | ``` |
| 113 | + | ||
| 113 | ## 参数说明 | 114 | ## 参数说明 |
| 114 | 115 | ||
| 115 | ### 无借位输出减法 | 116 | ### 无借位输出减法 |
| @@ -26,6 +26,7 @@ Ascend C API支持以下舍入模式: | |||
| 26 | ### 舍入模式详细说明 | 26 | ### 舍入模式详细说明 |
| 27 | 27 | ||
| 28 | #### RINT(四舍六入五成双) | 28 | #### RINT(四舍六入五成双) |
| 29 | + | ||
| 29 | 也称为"银行家舍入法",是一种统计学上最无偏的舍入方法。 | 30 | 也称为"银行家舍入法",是一种统计学上最无偏的舍入方法。 |
| 30 | - 当小数部分小于0.5时,向下舍入 | 31 | - 当小数部分小于0.5时,向下舍入 |
| 31 | - 当小数部分大于0.5时,向上舍入 | 32 | - 当小数部分大于0.5时,向上舍入 |
| @@ -41,6 +42,7 @@ Ascend C API支持以下舍入模式: | |||
| 41 | ``` | 42 | ``` |
| 42 | 43 | ||
| 43 | #### ROUND(四舍五入) | 44 | #### ROUND(四舍五入) |
| 45 | + | ||
| 44 | 最常用的舍入方法,符合日常习惯。 | 46 | 最常用的舍入方法,符合日常习惯。 |
| 45 | - 当小数部分小于0.5时,向下舍入 | 47 | - 当小数部分小于0.5时,向下舍入 |
| 46 | - 当小数部分大于等于0.5时,向上舍入 | 48 | - 当小数部分大于等于0.5时,向上舍入 |
| @@ -54,6 +56,7 @@ Ascend C API支持以下舍入模式: | |||
| 54 | ``` | 56 | ``` |
| 55 | 57 | ||
| 56 | #### FLOOR(向下取整) | 58 | #### FLOOR(向下取整) |
| 59 | + | ||
| 57 | 始终向负无穷方向舍入,即使结果变小。 | 60 | 始终向负无穷方向舍入,即使结果变小。 |
| 58 | 61 | ||
| 59 | **示例:** | 62 | **示例:** |
| @@ -63,6 +66,7 @@ Ascend C API支持以下舍入模式: | |||
| 63 | ``` | 66 | ``` |
| 64 | 67 | ||
| 65 | #### CEIL(向上取整) | 68 | #### CEIL(向上取整) |
| 69 | + | ||
| 66 | 始终向正无穷方向舍入,即使结果变大。 | 70 | 始终向正无穷方向舍入,即使结果变大。 |
| 67 | 71 | ||
| 68 | **示例:** | 72 | **示例:** |
| @@ -72,6 +76,7 @@ Ascend C API支持以下舍入模式: | |||
| 72 | ``` | 76 | ``` |
| 73 | 77 | ||
| 74 | #### TRUNC(向零截断) | 78 | #### TRUNC(向零截断) |
| 79 | + | ||
| 75 | 直接截断小数部分,向零方向舍入。 | 80 | 直接截断小数部分,向零方向舍入。 |
| 76 | 81 | ||
| 77 | **示例:** | 82 | **示例:** |
| @@ -81,6 +86,7 @@ Ascend C API支持以下舍入模式: | |||
| 81 | ``` | 86 | ``` |
| 82 | 87 | ||
| 83 | #### ODD(奇数舍入) | 88 | #### ODD(奇数舍入) |
| 89 | + | ||
| 84 | 舍入到最近的奇数,主要用于某些特殊的数值计算场景。 | 90 | 舍入到最近的奇数,主要用于某些特殊的数值计算场景。 |
| 85 | 91 | ||
| 86 | **示例:** | 92 | **示例:** |
| @@ -103,6 +109,7 @@ Ascend C API支持以下舍入模式: | |||
| 103 | 在非饱和模式下,当数据超出目标类型范围时: | 109 | 在非饱和模式下,当数据超出目标类型范围时: |
| 104 | 110 | ||
| 105 | #### 整型转换 | 111 | #### 整型转换 |
| 112 | + | ||
| 106 | - **结果被截断**:保留最低有效位(LSB),高位直接丢弃 | 113 | - **结果被截断**:保留最低有效位(LSB),高位直接丢弃 |
| 107 | - **二进制截断示例**:将int32转换为int8时,只保留低8位 | 114 | - **二进制截断示例**:将int32转换为int8时,只保留低8位 |
| 108 | 115 | ||
| @@ -125,6 +132,7 @@ Ascend C API支持以下舍入模式: | |||
| 125 | ``` | 132 | ``` |
| 126 | 133 | ||
| 127 | #### 浮点数转换 | 134 | #### 浮点数转换 |
| 135 | + | ||
| 128 | - **超出范围**:返回输出类型的对应符号inf值(正/负无穷) | 136 | - **超出范围**:返回输出类型的对应符号inf值(正/负无穷) |
| 129 | - **±inf输入**:返回±inf | 137 | - **±inf输入**:返回±inf |
| 130 | - **NaN输入**:返回NaN | 138 | - **NaN输入**:返回NaN |
| @@ -142,6 +150,7 @@ Ascend C API支持以下舍入模式: | |||
| 142 | ``` | 150 | ``` |
| 143 | 151 | ||
| 144 | #### 浮点转整型 | 152 | #### 浮点转整型 |
| 153 | + | ||
| 145 | - **超出范围**:结果被截断至目标格式的数据宽度 | 154 | - **超出范围**:结果被截断至目标格式的数据宽度 |
| 146 | - **±inf输入**:返回输出类型的最值 | 155 | - **±inf输入**:返回输出类型的最值 |
| 147 | - **NaN输入**:返回0 | 156 | - **NaN输入**:返回0 |
| @@ -163,6 +172,7 @@ Ascend C API支持以下舍入模式: | |||
| 163 | 在饱和模式下,当数据超出目标类型范围时,结果被限制在目标类型的可表示范围内: | 172 | 在饱和模式下,当数据超出目标类型范围时,结果被限制在目标类型的可表示范围内: |
| 164 | 173 | ||
| 165 | #### 整型转换 | 174 | #### 整型转换 |
| 175 | + | ||
| 166 | - **超出范围**:返回目标类型的最大值或最小值 | 176 | - **超出范围**:返回目标类型的最大值或最小值 |
| 167 | - **保持数值安全**:不会出现因截断导致的意外结果 | 177 | - **保持数值安全**:不会出现因截断导致的意外结果 |
| 168 | 178 | ||
| @@ -191,6 +201,7 @@ Ascend C API支持以下舍入模式: | |||
| 191 | ``` | 201 | ``` |
| 192 | 202 | ||
| 193 | #### 浮点数转换 | 203 | #### 浮点数转换 |
| 204 | + | ||
| 194 | - **超出范围**:返回输出类型的对应最值 | 205 | - **超出范围**:返回输出类型的对应最值 |
| 195 | - **±inf输入**:返回输出类型的对应最值 | 206 | - **±inf输入**:返回输出类型的对应最值 |
| 196 | - **NaN输入**:返回0 | 207 | - **NaN输入**:返回0 |
| @@ -211,6 +222,7 @@ Ascend C API支持以下舍入模式: | |||
| 211 | ``` | 222 | ``` |
| 212 | 223 | ||
| 213 | #### 浮点转整型 | 224 | #### 浮点转整型 |
| 225 | + | ||
| 214 | - **超出范围**:返回输出类型的对应最值 | 226 | - **超出范围**:返回输出类型的对应最值 |
| 215 | - **±inf输入**:返回输出类型的对应最值 | 227 | - **±inf输入**:返回输出类型的对应最值 |
| 216 | - **NaN输入**:返回0 | 228 | - **NaN输入**:返回0 |
| @@ -56,6 +56,7 @@ __simd_callee__ inline void asc_copy(vector_<dtype>& dst, | |||
| 56 | ``` | 56 | ``` |
| 57 | 57 | ||
| 58 | #### dtype支持数据类型 | 58 | #### dtype支持数据类型 |
| 59 | + | ||
| 59 | `dtype`取值为:`int8_t`、`uint8_t`、`int16_t`、`uint16_t`、`half`、`bfloat16_t`、`int32_t`、`uint32_t`、`float`。 | 60 | `dtype`取值为:`int8_t`、`uint8_t`、`int16_t`、`uint16_t`、`half`、`bfloat16_t`、`int32_t`、`uint32_t`、`float`。 |
| 60 | 61 | ||
| 61 | #### 函数原型典型示例 | 62 | #### 函数原型典型示例 |
| @@ -49,6 +49,7 @@ __simd_callee__ inline vector_<dtype> asc_mask(vector_<dtype> src, | |||
| 49 | ``` | 49 | ``` |
| 50 | 50 | ||
| 51 | #### dtype支持数据类型 | 51 | #### dtype支持数据类型 |
| 52 | + | ||
| 52 | `dtype`取值为:`int8_t`、`uint8_t`、`int16_t`、`uint16_t`、`half`、`bfloat16_t`、`int32_t`、`uint32_t`、`float`。 | 53 | `dtype`取值为:`int8_t`、`uint8_t`、`int16_t`、`uint16_t`、`half`、`bfloat16_t`、`int32_t`、`uint32_t`、`float`。 |
| 53 | 54 | ||
| 54 | #### 函数原型典型示例 | 55 | #### 函数原型典型示例 |
| @@ -52,6 +52,7 @@ __simd_callee__ inline vector_<dtype> asc_gather(vector_<dtype> src, | |||
| 52 | ``` | 52 | ``` |
| 53 | 53 | ||
| 54 | ### 支持数据类型列表 | 54 | ### 支持数据类型列表 |
| 55 | + | ||
| 55 | **表1** 寄存器源收集模式支持数据类型列表 | 56 | **表1** 寄存器源收集模式支持数据类型列表 |
| 56 | 57 | ||
| 57 | | dtype | index_dtype | | 58 | | dtype | index_dtype | |
| @@ -63,6 +63,7 @@ __simd_callee__ inline void asc_xor(vector_<dtype>& dst, | |||
| 63 | ``` | 63 | ``` |
| 64 | 64 | ||
| 65 | #### dtype支持数据类型 | 65 | #### dtype支持数据类型 |
| 66 | + | ||
| 66 | `dtype`支持的数据类型:`int8_t`、`uint8_t`、`int16_t`、`uint16_t`、`int32_t`、`uint32_t`。 | 67 | `dtype`支持的数据类型:`int8_t`、`uint8_t`、`int16_t`、`uint16_t`、`int32_t`、`uint32_t`。 |
| 67 | 68 | ||
| 68 | #### 函数原型典型示例 | 69 | #### 函数原型典型示例 |
| @@ -23,6 +23,7 @@ | |||
| 23 | <!-- npu="910" id7 --> | 23 | <!-- npu="910" id7 --> |
| 24 | - Atlas训练系列产品:不支持 | 24 | - Atlas训练系列产品:不支持 |
| 25 | <!-- end id7 --> | 25 | <!-- end id7 --> |
| 26 | + | ||
| 26 | ## 功能说明 | 27 | ## 功能说明 |
| 27 | 28 | ||
| 28 | 头文件路径为:`"c_api/reg_compute/compute/reg_permute_sel.h"`。 | 29 | 头文件路径为:`"c_api/reg_compute/compute/reg_permute_sel.h"`。 |
| @@ -72,6 +72,7 @@ __simd_callee__ inline void asc_unpack_upper(vector_<dtype_dst>& dst, | |||
| 72 | ``` | 72 | ``` |
| 73 | 73 | ||
| 74 | #### dtype支持数据类型 | 74 | #### dtype支持数据类型 |
| 75 | + | ||
| 75 | dtype_src与dtype_dst支持的数据类型对如下: | 76 | dtype_src与dtype_dst支持的数据类型对如下: |
| 76 | 77 | ||
| 77 | | dtype_src | dtype_dst | | 78 | | dtype_src | dtype_dst | |
| @@ -55,6 +55,7 @@ __simd_callee__ inline void asc_unsqueeze(vector_<dtype>& dst, | |||
| 55 | ``` | 55 | ``` |
| 56 | 56 | ||
| 57 | #### dtype支持数据类型 | 57 | #### dtype支持数据类型 |
| 58 | + | ||
| 58 | dtype支持的数据类型:int8_t、uint8_t、int16_t、uint16_t、int32_t、uint32_t。返回值类型接口通过函数名后缀区分数据类型,对应关系如下: | 59 | dtype支持的数据类型:int8_t、uint8_t、int16_t、uint16_t、int32_t、uint32_t。返回值类型接口通过函数名后缀区分数据类型,对应关系如下: |
| 59 | 60 | ||
| 60 | | 函数名后缀 | 数据类型 | | 61 | | 函数名后缀 | 数据类型 | |
| @@ -54,6 +54,7 @@ __simd_callee__ inline vector_<dst_dtype> asc_gather(__ubuf__ <src_dtype>* src, | |||
| 54 | ``` | 54 | ``` |
| 55 | 55 | ||
| 56 | ### 数据类型组合列表 | 56 | ### 数据类型组合列表 |
| 57 | + | ||
| 57 | **表1** UB源收集模式支持数据类型组合列表 | 58 | **表1** UB源收集模式支持数据类型组合列表 |
| 58 | 59 | ||
| 59 | | dst_dtype | src_dtype | index_dtype | | 60 | | dst_dtype | src_dtype | index_dtype | |
| @@ -63,6 +63,7 @@ __aicore__ inline void asc_max(__ubuf__ float* dst, __ubuf__ float* src0, __ubuf | |||
| 63 | ``` | 63 | ``` |
| 64 | 64 | ||
| 65 | ## 参数说明 | 65 | ## 参数说明 |
| 66 | + | ||
| 66 | **表1** 参数说明 | 67 | **表1** 参数说明 |
| 67 | 68 | ||
| 68 | | 参数名 | 输入/输出 | 描述 | | 69 | | 参数名 | 输入/输出 | 描述 | |
| @@ -71,6 +71,7 @@ $$ | |||
| 71 | PIPE_V | 71 | PIPE_V |
| 72 | 72 | ||
| 73 | ## 约束说明 | 73 | ## 约束说明 |
| 74 | + | ||
| 74 | - src只支持设置为正数。 | 75 | - src只支持设置为正数。 |
| 75 | - 操作数地址重叠约束请参考[通用地址重叠约束](../../general_description_and_constraints.md#通用地址重叠约束)。 | 76 | - 操作数地址重叠约束请参考[通用地址重叠约束](../../general_description_and_constraints.md#通用地址重叠约束)。 |
| 76 | - dst、src的起始地址需要32字节对齐。 | 77 | - dst、src的起始地址需要32字节对齐。 |
| @@ -35,6 +35,7 @@ dst = src0 >= src1 | |||
| 35 | $$ | 35 | $$ |
| 36 | 36 | ||
| 37 | ## 函数原型 | 37 | ## 函数原型 |
| 38 | + | ||
| 38 | - 高维切分计算 | 39 | - 高维切分计算 |
| 39 | 40 | ||
| 40 | ```cpp | 41 | ```cpp |
| @@ -39,6 +39,7 @@ src_i ,\quad src_i>0\\ | |||
| 39 | $$ | 39 | $$ |
| 40 | 40 | ||
| 41 | ## 函数原型 | 41 | ## 函数原型 |
| 42 | + | ||
| 42 | - 前n个数据计算 | 43 | - 前n个数据计算 |
| 43 | 44 | ||
| 44 | ```cpp | 45 | ```cpp |
| @@ -61,6 +61,7 @@ | |||
| 61 | PIPE_V | 61 | PIPE_V |
| 62 | 62 | ||
| 63 | ## 约束说明 | 63 | ## 约束说明 |
| 64 | + | ||
| 64 | - src_offset取值应保证src元素类型位宽对齐。 | 65 | - src_offset取值应保证src元素类型位宽对齐。 |
| 65 | - src加上src_offset偏移后的地址不能超出Unified Buffer(UB)大小数据的范围。 | 66 | - src加上src_offset偏移后的地址不能超出Unified Buffer(UB)大小数据的范围。 |
| 66 | - dst、src的起始地址需要32字节对齐。 | 67 | - dst、src的起始地址需要32字节对齐。 |
| @@ -120,6 +120,7 @@ PIPE_V | |||
| 120 | <!-- end id12 --> | 120 | <!-- end id12 --> |
| 121 | 121 | ||
| 122 | <!-- npu="950" id8 --> | 122 | <!-- npu="950" id8 --> |
| 123 | + | ||
| 123 | ## 调用示例 | 124 | ## 调用示例 |
| 124 | 125 | ||
| 125 | 以下示例将256个乱序float类型score及其index分别作为输入,通过[asc_bitsort](asc_bitsort.md)与`asc_mrgsort4`配合完成全局降序排序,每个输出数据单元包含一个score及其对应的index,占8字节,总体计算流程为: | 126 | 以下示例将256个乱序float类型score及其index分别作为输入,通过[asc_bitsort](asc_bitsort.md)与`asc_mrgsort4`配合完成全局降序排序,每个输出数据单元包含一个score及其对应的index,占8字节,总体计算流程为: |
| @@ -42,6 +42,7 @@ | |||
| 42 | ## 函数原型 | 42 | ## 函数原型 |
| 43 | 43 | ||
| 44 | <a id="operator-eq"></a> | 44 | <a id="operator-eq"></a> |
| 45 | + | ||
| 45 | ### operator== | 46 | ### operator== |
| 46 | 47 | ||
| 47 | ```cpp | 48 | ```cpp |
| @@ -59,6 +60,7 @@ __simd_callee__ inline reg_tensor<bool> operator==( | |||
| 59 | ``` | 60 | ``` |
| 60 | 61 | ||
| 61 | <a id="operator-ne"></a> | 62 | <a id="operator-ne"></a> |
| 63 | + | ||
| 62 | ### operator!= | 64 | ### operator!= |
| 63 | 65 | ||
| 64 | ```cpp | 66 | ```cpp |
| @@ -76,6 +78,7 @@ __simd_callee__ inline reg_tensor<bool> operator!=( | |||
| 76 | ``` | 78 | ``` |
| 77 | 79 | ||
| 78 | <a id="operator-lt"></a> | 80 | <a id="operator-lt"></a> |
| 81 | + | ||
| 79 | ### operator< | 82 | ### operator< |
| 80 | 83 | ||
| 81 | ```cpp | 84 | ```cpp |
| @@ -93,6 +96,7 @@ __simd_callee__ inline reg_tensor<bool> operator<( | |||
| 93 | ``` | 96 | ``` |
| 94 | 97 | ||
| 95 | <a id="operator-le"></a> | 98 | <a id="operator-le"></a> |
| 99 | + | ||
| 96 | ### operator<= | 100 | ### operator<= |
| 97 | 101 | ||
| 98 | ```cpp | 102 | ```cpp |
| @@ -110,6 +114,7 @@ __simd_callee__ inline reg_tensor<bool> operator<=( | |||
| 110 | ``` | 114 | ``` |
| 111 | 115 | ||
| 112 | <a id="operator-gt"></a> | 116 | <a id="operator-gt"></a> |
| 117 | + | ||
| 113 | ### operator> | 118 | ### operator> |
| 114 | 119 | ||
| 115 | ```cpp | 120 | ```cpp |
| @@ -127,6 +132,7 @@ __simd_callee__ inline reg_tensor<bool> operator>( | |||
| 127 | ``` | 132 | ``` |
| 128 | 133 | ||
| 129 | <a id="operator-ge"></a> | 134 | <a id="operator-ge"></a> |
| 135 | + | ||
| 130 | ### operator>= | 136 | ### operator>= |
| 131 | 137 | ||
| 132 | ```cpp | 138 | ```cpp |
| @@ -118,6 +118,7 @@ __simd_callee__ inline void asc_dump(__ubuf__ T* input, uint32_t desc, uint32_t | |||
| 118 | | dump_size | 输入 | 所需要打印的元素数量。 | | 118 | | dump_size | 输入 | 所需要打印的元素数量。 | |
| 119 | 119 | ||
| 120 | ## 数据类型 | 120 | ## 数据类型 |
| 121 | + | ||
| 121 | <!-- npu="950" id10 --> | 122 | <!-- npu="950" id10 --> |
| 122 | - 针对Ascend 950PR&950DT系列产品 :bool、int8_t、uint8_t、hifloat8_t、fp8_e8m0_t、fp8_e5m2_t、fp8_e4m3fn_t、int16_t、uint16_t、half、bfloat16_t、int32_t、uint32_t、float、int64_t、uint64_t。 | 123 | - 针对Ascend 950PR&950DT系列产品 :bool、int8_t、uint8_t、hifloat8_t、fp8_e8m0_t、fp8_e5m2_t、fp8_e4m3fn_t、int16_t、uint16_t、half、bfloat16_t、int32_t、uint32_t、float、int64_t、uint64_t。 |
| 123 | <!-- end id10 --> | 124 | <!-- end id10 --> |
| @@ -40,6 +40,7 @@ | |||
| 40 | 此接口后续版本会废弃,请使用[asc_set_atomic_min_int32](../SIMD-API/c_api/atomic/datamove_atomic/asc_set_atomic_min.md)接口。 | 40 | 此接口后续版本会废弃,请使用[asc_set_atomic_min_int32](../SIMD-API/c_api/atomic/datamove_atomic/asc_set_atomic_min.md)接口。 |
| 41 | 41 | ||
| 42 | <!-- npu="950" id2 --> | 42 | <!-- npu="950" id2 --> |
| 43 | + | ||
| 43 | ### 系统变量 | 44 | ### 系统变量 |
| 44 | 45 | ||
| 45 | - [asc_get_block_idx](../SIMD-API/c_api/deprecated_interface/asc_get_block_idx_deprecated.md)接口 | 46 | - [asc_get_block_idx](../SIMD-API/c_api/deprecated_interface/asc_get_block_idx_deprecated.md)接口 |
| @@ -59,6 +60,7 @@ | |||
| 59 | <!-- end id2 --> | 60 | <!-- end id2 --> |
| 60 | 61 | ||
| 61 | <!-- npu="950" id3 --> | 62 | <!-- npu="950" id3 --> |
| 63 | + | ||
| 62 | ### Reg矢量计算 | 64 | ### Reg矢量计算 |
| 63 | 65 | ||
| 64 | #### Reg数据搬入 | 66 | #### Reg数据搬入 |
| @@ -212,6 +214,7 @@ | |||
| 212 | <!-- end id3 --> | 214 | <!-- end id3 --> |
| 213 | 215 | ||
| 214 | <!-- npu="950" id4 --> | 216 | <!-- npu="950" id4 --> |
| 217 | + | ||
| 215 | #### 逻辑计算 | 218 | #### 逻辑计算 |
| 216 | 219 | ||
| 217 | - [asc_and](../SIMD-API/c_api/deprecated_interface/asc_and_deprecated.md)接口(浮点类型重载) | 220 | - [asc_and](../SIMD-API/c_api/deprecated_interface/asc_and_deprecated.md)接口(浮点类型重载) |
| @@ -508,6 +511,7 @@ | |||
| 508 | 511 | ||
| 509 | 使用`uint8_t unit_flag`入参的`asc_mmad_sparse()`接口已废弃,请使用[asc_mmad_sparse](../SIMD-API/c_api/cube_compute/asc_mmad_sparse.md)接口。`asc_mmad_sparse_sync()`接口已废弃,请使用[asc_mmad_sparse](../SIMD-API/c_api/cube_compute/asc_mmad_sparse.md)接口和[asc_sync](../SIMD-API/c_api/sync/intra_core_sync/asc_sync.md)接口。 | 512 | 使用`uint8_t unit_flag`入参的`asc_mmad_sparse()`接口已废弃,请使用[asc_mmad_sparse](../SIMD-API/c_api/cube_compute/asc_mmad_sparse.md)接口。`asc_mmad_sparse_sync()`接口已废弃,请使用[asc_mmad_sparse](../SIMD-API/c_api/cube_compute/asc_mmad_sparse.md)接口和[asc_sync](../SIMD-API/c_api/sync/intra_core_sync/asc_sync.md)接口。 |
| 510 | <!-- end id6 --> | 513 | <!-- end id6 --> |
| 514 | + | ||
| 511 | ### 矩阵计算搬运 | 515 | ### 矩阵计算搬运 |
| 512 | 516 | ||
| 513 | - [asc_copy_gm2l0a_sync(废弃)](../SIMD-API/c_api/deprecated_interface/asc_copy_gm2l0a_sync_deprecated.md)接口 | 517 | - [asc_copy_gm2l0a_sync(废弃)](../SIMD-API/c_api/deprecated_interface/asc_copy_gm2l0a_sync_deprecated.md)接口 |
| @@ -7,6 +7,7 @@ | |||
| 7 | <!-- end id1 --> | 7 | <!-- end id1 --> |
| 8 | 8 | ||
| 9 | ## 边界值说明 | 9 | ## 边界值说明 |
| 10 | + | ||
| 10 | - fp4x2_e1m2_t和fp4x2_e2m1_t数据类型没有+inf/-inf/nan定义,从其他数据类型的+inf/-inf/nan转换为这两种数据类型时会被直接转换为边界值或0。值转换情况如下表所示: | 11 | - fp4x2_e1m2_t和fp4x2_e2m1_t数据类型没有+inf/-inf/nan定义,从其他数据类型的+inf/-inf/nan转换为这两种数据类型时会被直接转换为边界值或0。值转换情况如下表所示: |
| 11 | 12 | ||
| 12 | **表1** fp4x2_e1m2_t和fp4x2_e2m1_t数据类型边界值转换结果 | 13 | **表1** fp4x2_e1m2_t和fp4x2_e2m1_t数据类型边界值转换结果 |
| @@ -1,6 +1,7 @@ | |||
| 1 | # Ascend C概述 | 1 | # Ascend C概述 |
| 2 | 2 | ||
| 3 | ## CANN概述 | 3 | ## CANN概述 |
| 4 | + | ||
| 4 | AI(Artificial Intelligence,人工智能)芯片是专为加速人工智能计算任务设计的专用处理器,凭借高度并行化的硬件架构,可高效应对深度学习场景中的大规模张量运算。NPU(Neural-Network Processing Unit,神经网络处理器)作为AI芯片的典型代表,其核心优势在于适配神经网络任务的高效执行;昇腾AI处理器作为专用NPU,内部集成大量高性能计算核心,进一步强化了这一硬件优势,为AI任务的高效运行提供坚实支撑。 | 5 | AI(Artificial Intelligence,人工智能)芯片是专为加速人工智能计算任务设计的专用处理器,凭借高度并行化的硬件架构,可高效应对深度学习场景中的大规模张量运算。NPU(Neural-Network Processing Unit,神经网络处理器)作为AI芯片的典型代表,其核心优势在于适配神经网络任务的高效执行;昇腾AI处理器作为专用NPU,内部集成大量高性能计算核心,进一步强化了这一硬件优势,为AI任务的高效运行提供坚实支撑。 |
| 5 | 6 | ||
| 6 | 在神经网络模型中,算子是构成模型的基础计算单元,封装了针对张量数据的特定数学操作逻辑,如卷积、矩阵乘、激活函数等。神经网络模型的推理与训练过程,本质上是一系列算子按照预设逻辑有序执行、协同完成计算任务的过程。为充分释放昇腾NPU的硬件算力,需构建一套能够高效衔接上层AI框架与底层硬件的软件平台,而CANN(Compute Architecture for Neural Networks)正是华为专为昇腾NPU打造的全栈软件解决方案。 | 7 | 在神经网络模型中,算子是构成模型的基础计算单元,封装了针对张量数据的特定数学操作逻辑,如卷积、矩阵乘、激活函数等。神经网络模型的推理与训练过程,本质上是一系列算子按照预设逻辑有序执行、协同完成计算任务的过程。为充分释放昇腾NPU的硬件算力,需构建一套能够高效衔接上层AI框架与底层硬件的软件平台,而CANN(Compute Architecture for Neural Networks)正是华为专为昇腾NPU打造的全栈软件解决方案。 |
| @@ -8,6 +9,7 @@ AI(Artificial Intelligence,人工智能)芯片是专为加速人工智能 | |||
| 8 | CANN基于分层架构设计,实现了上层应用与底层硬件的无缝衔接。向上,兼容PyTorch等主流AI框架,确保应用层的兼容性与易用性;向下,深度适配昇腾AI处理器,充分发挥硬件的计算潜能,进而构建起CPU与NPU深度融合的异构计算体系。在该体系中,CANN通过Runtime运行时接口驱动CPU与NPU高效协同调度:CPU完成数据准备、任务拆解与调度后,将算子任务下发至NPU加速执行;计算完成后,结果由CPU回收或根据业务需求进行进一步处理。这一协同机制贯穿算子、模型、应用全层级,有效达成计算性能与运行效率的最优平衡,为昇腾AI处理器算力的充分释放提供核心软件支撑。 | 9 | CANN基于分层架构设计,实现了上层应用与底层硬件的无缝衔接。向上,兼容PyTorch等主流AI框架,确保应用层的兼容性与易用性;向下,深度适配昇腾AI处理器,充分发挥硬件的计算潜能,进而构建起CPU与NPU深度融合的异构计算体系。在该体系中,CANN通过Runtime运行时接口驱动CPU与NPU高效协同调度:CPU完成数据准备、任务拆解与调度后,将算子任务下发至NPU加速执行;计算完成后,结果由CPU回收或根据业务需求进行进一步处理。这一协同机制贯穿算子、模型、应用全层级,有效达成计算性能与运行效率的最优平衡,为昇腾AI处理器算力的充分释放提供核心软件支撑。 |
| 9 | 10 | ||
| 10 | ## Ascend C简介 | 11 | ## Ascend C简介 |
| 12 | + | ||
| 11 | 大模型时代,算力需求正以前所未有的速度激增。如何开发高性能算子,充分释放硬件每一分潜能,已成为决定AI应用落地的关键。为帮助开发者高效构建可直接运行于NPU的高性能算子,Ascend C应运而生。Ascend C是CANN生态下,面向昇腾AI处理器推出的专用算子开发语言,原生兼容C与C++标准规范。此外,Ascend C秉持**开放芯片完备编程能力,支撑极致性能**的设计理念,构建多层级API体系,满足多场景算子开发诉求,让您能够根据项目需求、团队技能和性能目标,在开发效率与运行性能之间灵活权衡,实现最优平衡。 | 13 | 大模型时代,算力需求正以前所未有的速度激增。如何开发高性能算子,充分释放硬件每一分潜能,已成为决定AI应用落地的关键。为帮助开发者高效构建可直接运行于NPU的高性能算子,Ascend C应运而生。Ascend C是CANN生态下,面向昇腾AI处理器推出的专用算子开发语言,原生兼容C与C++标准规范。此外,Ascend C秉持**开放芯片完备编程能力,支撑极致性能**的设计理念,构建多层级API体系,满足多场景算子开发诉求,让您能够根据项目需求、团队技能和性能目标,在开发效率与运行性能之间灵活权衡,实现最优平衡。 |
| 12 | 14 | ||
| 13 | 为满足不同场景的诉求,Ascend C构建了从单指令抽象、单核公共算法到多核算子的多层级API体系,其总体逻辑架构如下: | 15 | 为满足不同场景的诉求,Ascend C构建了从单指令抽象、单核公共算法到多核算子的多层级API体系,其总体逻辑架构如下: |
| @@ -42,6 +42,7 @@ UB_ADDR[18:0] = {BANK_DEPTH[8:0], BANK[0], BG[2:0], BANK_WIDTH[4:0]} | |||
| 42 | **注:bank冲突的场景与UB的规格密切相关,规格的变化通常会导致bank冲突场景的变化。** | 42 | **注:bank冲突的场景与UB的规格密切相关,规格的变化通常会导致bank冲突场景的变化。** |
| 43 | 43 | ||
| 44 | ### 基于连续访存的bank冲突分析 | 44 | ### 基于连续访存的bank冲突分析 |
| 45 | + | ||
| 45 | 以下对连续访存的冲突类型进行解读: | 46 | 以下对连续访存的冲突类型进行解读: |
| 46 | 47 | ||
| 47 | - 读写冲突 | 48 | - 读写冲突 |
| @@ -239,6 +240,7 @@ UB_ADDR[18:0] = {BANK_DEPTH[8:0], BANK[0], BG[2:0], BANK_WIDTH[4:0]} | |||
| 239 | </table> | 240 | </table> |
| 240 | 241 | ||
| 241 | ### 基于离散访存的bank冲突分析 | 242 | ### 基于离散访存的bank冲突分析 |
| 243 | + | ||
| 242 | 以下对离散访存下的冲突进行解读: | 244 | 以下对离散访存下的冲突进行解读: |
| 243 | 245 | ||
| 244 | - 当gather/scatter访存数据分布在不同的subbank中时,不发生冲突。 | 246 | - 当gather/scatter访存数据分布在不同的subbank中时,不发生冲突。 |
| @@ -91,6 +91,7 @@ for (uint16_t i = 0; i < 32; ++i) { // VLoop-2 | |||
| 91 | > 循环展开通过消除指令依赖,提升指令双发能力来优化VF性能,需根据实际计算过程使用,不保证产生收益。展开时,若寄存器超出数量上限,可能会造成性能劣化或其他非预期行为。 | 91 | > 循环展开通过消除指令依赖,提升指令双发能力来优化VF性能,需根据实际计算过程使用,不保证产生收益。展开时,若寄存器超出数量上限,可能会造成性能劣化或其他非预期行为。 |
| 92 | 92 | ||
| 93 | ### 手动展开VF循环 | 93 | ### 手动展开VF循环 |
| 94 | + | ||
| 94 | ```cpp | 95 | ```cpp |
| 95 | for (uint16_t i = 0; i < 32; ++i) { | 96 | for (uint16_t i = 0; i < 32; ++i) { |
| 96 | // for循环间没有依赖关系:i=0,i=1可以并行执行,但是由于循环内数据依赖指令过多导致i=1的指令无法加载进执行队列中 | 97 | // for循环间没有依赖关系:i=0,i=1可以并行执行,但是由于循环内数据依赖指令过多导致i=1的指令无法加载进执行队列中 |
| @@ -127,6 +128,7 @@ for (uint16_t i = 0; i < 8; ++i) { // 32做4展开 | |||
| 127 | ``` | 128 | ``` |
| 128 | 129 | ||
| 129 | ### 编译器自动展开 | 130 | ### 编译器自动展开 |
| 131 | + | ||
| 130 | ```cpp | 132 | ```cpp |
| 131 | #pragma unroll 4 | 133 | #pragma unroll 4 |
| 132 | for (uint16_t i = 0; i < 32; ++i) { | 134 | for (uint16_t i = 0; i < 32; ++i) { |
Mdocs/zh/guide/operator_practice/simt_operator_optimization/execution_config/thread_block_config.md+1-0
| @@ -19,6 +19,7 @@ | |||
| 19 | 本优化方法对应的样例请参见[核函数(Kernel)的启动配置性能调优样例](../../../../../../examples/03_simt_api/03_best_practices/01_execution_conf_optimizations/grid_dim_config/README.md)。 | 19 | 本优化方法对应的样例请参见[核函数(Kernel)的启动配置性能调优样例](../../../../../../examples/03_simt_api/03_best_practices/01_execution_conf_optimizations/grid_dim_config/README.md)。 |
| 20 | 20 | ||
| 21 | ## 大数据量场景 | 21 | ## 大数据量场景 |
| 22 | + | ||
| 22 | 下面以Gather算子为例,对比大数据量场景(`1024*2048`,即2097152个元素)下不同线程块数量配置的性能差异。 | 23 | 下面以Gather算子为例,对比大数据量场景(`1024*2048`,即2097152个元素)下不同线程块数量配置的性能差异。 |
| 23 | 24 | ||
| 24 | 【反例】一个线程处理一个元素,随数据量增加线程块个数,导致需要启动和调度的线程块大幅增加。 | 25 | 【反例】一个线程处理一个元素,随数据量增加线程块个数,导致需要启动和调度的线程块大幅增加。 |
| @@ -125,6 +125,7 @@ AscendC::DumpTensor(zLocal, 1, 32); | |||
| 125 | ## 性能调试 | 125 | ## 性能调试 |
| 126 | 126 | ||
| 127 | ### msOpProf工具介绍 | 127 | ### msOpProf工具介绍 |
| 128 | + | ||
| 128 | msOpProf工具是单算子性能分析工具。包含msopprof和msopprof simulator两种使用方式。该工具协助用户定位算子内存、算子代码以及算子指令的异常,实现全方位的算子调优。当前支持基于不同运行模式(上板或仿真)和不同文件形式(可执行文件或算子二进制.o文件)进行性能数据的采集和自动解析。 | 129 | msOpProf工具是单算子性能分析工具。包含msopprof和msopprof simulator两种使用方式。该工具协助用户定位算子内存、算子代码以及算子指令的异常,实现全方位的算子调优。当前支持基于不同运行模式(上板或仿真)和不同文件形式(可执行文件或算子二进制.o文件)进行性能数据的采集和自动解析。 |
| 129 | 130 | ||
| 130 | - 上板性能采集 | 131 | - 上板性能采集 |
| @@ -215,6 +215,7 @@ npu_op_kernel_options(<target_name> <op_type> [COMPUTE_UNIT <soc_version>... | S | |||
| 215 | npu_op_kernel_options(ascendc_kernels ALL OPTIONS --save-temp-files -g) #为算子添加编译选项 | 215 | npu_op_kernel_options(ascendc_kernels ALL OPTIONS --save-temp-files -g) #为算子添加编译选项 |
| 216 | ``` | 216 | ``` |
| 217 | npu_op_kernel_options(ascendc_kernels AddCustom SOC_SERIES Ascendxxx Ascendyyy OPTIONS -DASCENDC_DEBUG) | 217 | npu_op_kernel_options(ascendc_kernels AddCustom SOC_SERIES Ascendxxx Ascendyyy OPTIONS -DASCENDC_DEBUG) |
| 218 | + | ||
| 218 | ### npu_op_kernel_sources | 219 | ### npu_op_kernel_sources |
| 219 | 220 | ||
| 220 | 描述核函数(Kernel)目标的源码信息,包括设置算子的核函数(Kernel)实现文件和源码路径等。 | 221 | 描述核函数(Kernel)目标的源码信息,包括设置算子的核函数(Kernel)实现文件和源码路径等。 |
| @@ -251,6 +252,7 @@ npu_op_kernel_sources(ascendc_kernels | |||
| 251 | KERNEL_FILE add_custom.cpp | 252 | KERNEL_FILE add_custom.cpp |
| 252 | ) | 253 | ) |
| 253 | ``` | 254 | ``` |
| 255 | + | ||
| 254 | ### npu_op_device_tiling_library | 256 | ### npu_op_device_tiling_library |
| 255 | 257 | ||
| 256 | 创建Device侧Tiling库。使用该选项时,package的类型仅支持配置为RUN(run包模式)。 | 258 | 创建Device侧Tiling库。使用该选项时,package的类型仅支持配置为RUN(run包模式)。 |
| @@ -148,6 +148,7 @@ export ASCENDC_BUILD_LOG_DIR=/home/build_log/ | |||
| 148 | ``` | 148 | ``` |
| 149 | 149 | ||
| 150 | <a id="算子包部署"></a> | 150 | <a id="算子包部署"></a> |
| 151 | + | ||
| 151 | ## 算子包部署<a id="operator-package-deployment"></a> | 152 | ## 算子包部署<a id="operator-package-deployment"></a> |
| 152 | 153 | ||
| 153 | 编译生成的算子安装包需要部署到运行环境。 | 154 | 编译生成的算子安装包需要部署到运行环境。 |
| @@ -184,6 +185,7 @@ source /usr/local/Ascend/cann/set_env.sh | |||
| 184 | > - 算子包要求架构与系统架构一致,且满足glibc版本依赖,否则可使用`--force`强制安装。 | 185 | > - 算子包要求架构与系统架构一致,且满足glibc版本依赖,否则可使用`--force`强制安装。 |
| 185 | 186 | ||
| 186 | <a id="部署后的目录结构"></a> | 187 | <a id="部署后的目录结构"></a> |
| 188 | + | ||
| 187 | ### 部署后的目录结构 | 189 | ### 部署后的目录结构 |
| 188 | 190 | ||
| 189 | 以默认安装场景为例: | 191 | 以默认安装场景为例: |
| @@ -223,6 +225,7 @@ source /usr/local/Ascend/cann/set_env.sh | |||
| 223 | ``` | 225 | ``` |
| 224 | 226 | ||
| 225 | <a id="配置自定义算子优先级"></a> | 227 | <a id="配置自定义算子优先级"></a> |
| 228 | + | ||
| 226 | ### 配置自定义算子优先级 | 229 | ### 配置自定义算子优先级 |
| 227 | 230 | ||
| 228 | 多个算子包共存时,如果包含相同OpType的算子,优先级高的算子包中的版本生效。 | 231 | 多个算子包共存时,如果包含相同OpType的算子,优先级高的算子包中的版本生效。 |
| @@ -313,6 +316,7 @@ source /usr/local/Ascend/cann/set_env.sh | |||
| 313 | --- | 316 | --- |
| 314 | 317 | ||
| 315 | <a id="编译组织"></a> | 318 | <a id="编译组织"></a> |
| 319 | + | ||
| 316 | ## 编译组织(进阶)<a id="advanced-build-organization"></a> | 320 | ## 编译组织(进阶)<a id="advanced-build-organization"></a> |
| 317 | 321 | ||
| 318 | 算子工程通过CMake组织编译。如需自行组织工程或用CANN提供的CMake modules定制编译流程,可参考以下内容。 | 322 | 算子工程通过CMake组织编译。如需自行组织工程或用CANN提供的CMake modules定制编译流程,可参考以下内容。 |
| @@ -613,6 +617,7 @@ npu_op_package_add(${package_name} | |||
| 613 | 完成编译组织之后,可按照[基本流程](#基本流程)的三个步骤完成算子编译与部署。 | 617 | 完成编译组织之后,可按照[基本流程](#基本流程)的三个步骤完成算子编译与部署。 |
| 614 | 618 | ||
| 615 | <a id="自定义编译选项"></a> | 619 | <a id="自定义编译选项"></a> |
| 620 | + | ||
| 616 | ## 自定义编译选项(进阶)<a id="custom-compile-options"></a> | 621 | ## 自定义编译选项(进阶)<a id="custom-compile-options"></a> |
| 617 | 622 | ||
| 618 | 在CMakeLists.txt中,用`npu_op_kernel_options`为核函数(Kernel)侧代码添加编译选项: | 623 | 在CMakeLists.txt中,用`npu_op_kernel_options`为核函数(Kernel)侧代码添加编译选项: |
| @@ -147,6 +147,7 @@ ccache --show-stats -v | |||
| 147 | 147 | ||
| 148 | 148 | ||
| 149 | <a id="选择性编译"></a> | 149 | <a id="选择性编译"></a> |
| 150 | + | ||
| 150 | ## 选择性编译 | 151 | ## 选择性编译 |
| 151 | 152 | ||
| 152 | 选择性编译的核心思路是:开发调试阶段只编译当前真正需要验证的部分,减少无关核函数(Kernel)变体、无关芯片和无关产物带来的编译开销。常用策略如下: | 153 | 选择性编译的核心思路是:开发调试阶段只编译当前真正需要验证的部分,减少无关核函数(Kernel)变体、无关芯片和无关产物带来的编译开销。常用策略如下: |
| @@ -245,6 +246,7 @@ npu_op_kernel_options(ascendc_kernels AddCustomTemplate COMPUTE_UNIT Ascendxxyy | |||
| 245 | cmake -S . -B build_out --preset=default -DASCEND_SOC_SERIES=ascendxxx | 246 | cmake -S . -B build_out --preset=default -DASCEND_SOC_SERIES=ascendxxx |
| 246 | ``` | 247 | ``` |
| 247 | 也可以使用参数`-DASCEND_COMPUTE_UNIT=ascendxxxyy`;两个参数不能同时传入。 | 248 | 也可以使用参数`-DASCEND_COMPUTE_UNIT=ascendxxxyy`;两个参数不能同时传入。 |
| 249 | + | ||
| 248 | ### 跳过核函数(Kernel)二进制编译 | 250 | ### 跳过核函数(Kernel)二进制编译 |
| 249 | 251 | ||
| 250 | 如果当前只需要生成源码包,或暂时不需要核函数(Kernel) `.o`二进制,可关闭二进制包生成。顶层`CMakeLists.txt`中应使用变量形式传递`ENABLE_BINARY_PACKAGE`: | 252 | 如果当前只需要生成源码包,或暂时不需要核函数(Kernel) `.o`二进制,可关闭二进制包生成。顶层`CMakeLists.txt`中应使用变量形式传递`ENABLE_BINARY_PACKAGE`: |
| @@ -313,6 +313,7 @@ aclnnStatus aclnnXxxTensorGetWorkspaceSize(const aclTensor *src, ..., aclTensor | |||
| 313 | aclnnStatus aclnnXxxGetWorkspaceSize(const aclIntArray *x0, const aclBoolArray *x1, const aclFloatArray *x2, aclTensor *out, uint64_t *workspaceSize, aclOpExecutor **executor); | 313 | aclnnStatus aclnnXxxGetWorkspaceSize(const aclIntArray *x0, const aclBoolArray *x1, const aclFloatArray *x2, aclTensor *out, uint64_t *workspaceSize, aclOpExecutor **executor); |
| 314 | aclnnStatus aclnnXxxTensorGetWorkspaceSize(const aclTensor *x0, const aclTensor *x1, const aclTensor *x2, aclTensor *out, uint64_t *workspaceSize, aclOpExecutor **executor); | 314 | aclnnStatus aclnnXxxTensorGetWorkspaceSize(const aclTensor *x0, const aclTensor *x1, const aclTensor *x2, aclTensor *out, uint64_t *workspaceSize, aclOpExecutor **executor); |
| 315 | ``` | 315 | ``` |
| 316 | + | ||
| 316 | ## 相关文档 | 317 | ## 相关文档 |
| 317 | 318 | ||
| 318 | - [快速入门](../aclnn_quick_start.md) — 创建并跑通AddCustom算子工程。 | 319 | - [快速入门](../aclnn_quick_start.md) — 创建并跑通AddCustom算子工程。 |
| @@ -220,6 +220,7 @@ T6 Scalar.LOAD A -> 1 | |||
| 220 | 还有一类问题来自Cache Line粒度。普通Scalar写后续以64B Cache Line为单位写回;多个核即使写的是同一条Cache Line中的不同字段,也可能在各自写回整条Cache Line时覆盖对方结果。此类场景可以通过让不同核操作的地址至少相隔Cache Line大小,或使用ReadGmBypassDCache和WriteGmBypassDCache降低风险。 | 220 | 还有一类问题来自Cache Line粒度。普通Scalar写后续以64B Cache Line为单位写回;多个核即使写的是同一条Cache Line中的不同字段,也可能在各自写回整条Cache Line时覆盖对方结果。此类场景可以通过让不同核操作的地址至少相隔Cache Line大小,或使用ReadGmBypassDCache和WriteGmBypassDCache降低风险。 |
| 221 | 221 | ||
| 222 | <!-- npu="950" id3 --> | 222 | <!-- npu="950" id3 --> |
| 223 | + | ||
| 223 | #### Atomic访问导致的DCache缓存一致性 | 224 | #### Atomic访问导致的DCache缓存一致性 |
| 224 | 225 | ||
| 225 | [NPU架构版本3510](../../language_extension/simd_builtin_keywords.md)支持Scalar原子操作,Scalar原子操作可以看成对某个GM地址执行的读-改-写事件,但是Scalar原子操作会绕过DCache,因此会导致缓存一致性。例如C API [asc_atomic_add](../../../../api/SIMD-API/c_api/atomic/scalar_atomic/asc_atomic_add.md),该接口在指定GM地址上执行原子加操作。原子操作保证的是这一次读-改-写不会被其他原子更新打断,但它不会自动清理同一地址在DCache中的旧副本或Dirty副本。 | 226 | [NPU架构版本3510](../../language_extension/simd_builtin_keywords.md)支持Scalar原子操作,Scalar原子操作可以看成对某个GM地址执行的读-改-写事件,但是Scalar原子操作会绕过DCache,因此会导致缓存一致性。例如C API [asc_atomic_add](../../../../api/SIMD-API/c_api/atomic/scalar_atomic/asc_atomic_add.md),该接口在指定GM地址上执行原子加操作。原子操作保证的是这一次读-改-写不会被其他原子更新打断,但它不会自动清理同一地址在DCache中的旧副本或Dirty副本。 |
| @@ -448,6 +449,7 @@ ICache用于缓存Scalar单元最近使用或频繁使用的指令。Scalar读 | |||
| 448 | 从缓存一致性角度看,ICache缓存的是指令而不是普通数据,并且是只读Cache,因此一般不涉及普通数据路径上的Cache副本不一致问题。 | 449 | 从缓存一致性角度看,ICache缓存的是指令而不是普通数据,并且是只读Cache,因此一般不涉及普通数据路径上的Cache副本不一致问题。 |
| 449 | 450 | ||
| 450 | <!-- npu="950" id4 --> | 451 | <!-- npu="950" id4 --> |
| 452 | + | ||
| 451 | ### SIMT DCache与GM的缓存一致性 | 453 | ### SIMT DCache与GM的缓存一致性 |
| 452 | 454 | ||
| 453 | #### SIMT DCache访问路径 | 455 | #### SIMT DCache访问路径 |
| @@ -608,6 +610,7 @@ C API中提供了[`asc_ub_dcci_single`](../../../../api/SIMD-API/c_api/cache_ctr | |||
| 608 | 下面按atomic事件发起路径分类说明:<!-- npu="950" id6 -->Scalar原子、<!-- end id6 -->MTE3随路原子、FixPipe随路原子<!-- npu="950" id7 -->和SIMT原子<!-- end id7 -->。本节只说明这些atomic事件放入一致性分析时需要关注的Cache行为,接口细节可参考对应API文档。 | 610 | 下面按atomic事件发起路径分类说明:<!-- npu="950" id6 -->Scalar原子、<!-- end id6 -->MTE3随路原子、FixPipe随路原子<!-- npu="950" id7 -->和SIMT原子<!-- end id7 -->。本节只说明这些atomic事件放入一致性分析时需要关注的Cache行为,接口细节可参考对应API文档。 |
| 609 | 611 | ||
| 610 | <!-- npu="950" id8 --> | 612 | <!-- npu="950" id8 --> |
| 613 | + | ||
| 611 | ### Scalar原子操作与DCache一致性 | 614 | ### Scalar原子操作与DCache一致性 |
| 612 | 615 | ||
| 613 | [NPU架构版本3510](../../language_extension/simd_builtin_keywords.md)支持Scalar原子操作,Scalar原子操作和普通Scalar读写GM混用时,需要按DCache与GM的一致性来分析,详细处理方式参考[Atomic访问导致的DCache缓存一致性](#atomic访问导致的dcache缓存一致性)。 | 616 | [NPU架构版本3510](../../language_extension/simd_builtin_keywords.md)支持Scalar原子操作,Scalar原子操作和普通Scalar读写GM混用时,需要按DCache与GM的一致性来分析,详细处理方式参考[Atomic访问导致的DCache缓存一致性](#atomic访问导致的dcache缓存一致性)。 |
| @@ -635,6 +638,7 @@ FixPipe常用于`L0C Buffer -> GM`或相关矩阵搬出路径。对一致性分 | |||
| 635 | - 如果多个流水或多个核都对同一GM地址做随路原子,原子操作只保证每次GM读-改-写不被打断;不同流水、不同核之间的启动顺序仍应由同步或算法协议保证。 | 638 | - 如果多个流水或多个核都对同一GM地址做随路原子,原子操作只保证每次GM读-改-写不被打断;不同流水、不同核之间的启动顺序仍应由同步或算法协议保证。 |
| 636 | 639 | ||
| 637 | <!-- npu="950" id9 --> | 640 | <!-- npu="950" id9 --> |
| 641 | + | ||
| 638 | ### SIMT原子操作与缓存一致性 | 642 | ### SIMT原子操作与缓存一致性 |
| 639 | 643 | ||
| 640 | [NPU架构版本3510](../../language_extension/simd_builtin_keywords.md)支持SIMT原子操作,SIMT原子操作可能作用于UB,也可能作用于GM;接口例子可参考[asc_atomic_add](../../../../api/SIMT-API/atomic_operations/asc_atomic_add.md)。它保证的是同一地址上这一次读-改-写具有原子性,不保证多个线程之间的执行顺序。 | 644 | [NPU架构版本3510](../../language_extension/simd_builtin_keywords.md)支持SIMT原子操作,SIMT原子操作可能作用于UB,也可能作用于GM;接口例子可参考[asc_atomic_add](../../../../api/SIMT-API/atomic_operations/asc_atomic_add.md)。它保证的是同一地址上这一次读-改-写具有原子性,不保证多个线程之间的执行顺序。 |
| @@ -115,6 +115,7 @@ Scalar负责标量控制、地址计算、标量计算、Scalar访存以及发 | |||
| 115 | MTE/Fixpipe指令无论是否访问同地址,指令间内存访问的实际完成顺序或对外可见顺序可能与代码顺序不一致,硬件不保证内存一致性。如果前后指令存在重叠地址或数据依赖,需要显式等待前序指令的数据读写完成。 | 115 | MTE/Fixpipe指令无论是否访问同地址,指令间内存访问的实际完成顺序或对外可见顺序可能与代码顺序不一致,硬件不保证内存一致性。如果前后指令存在重叠地址或数据依赖,需要显式等待前序指令的数据读写完成。 |
| 116 | 116 | ||
| 117 | <!-- npu="950" id4 --> | 117 | <!-- npu="950" id4 --> |
| 118 | + | ||
| 118 | ##### SIMT流水 | 119 | ##### SIMT流水 |
| 119 | 120 | ||
| 120 | SIMT流水用于SIMT编程模型中的线程级执行,适合复杂控制流和不规则访存场景。SIMT线程可以访问GM,也支持线程同步、MEMBAR和原子操作。 | 121 | SIMT流水用于SIMT编程模型中的线程级执行,适合复杂控制流和不规则访存场景。SIMT线程可以访问GM,也支持线程同步、MEMBAR和原子操作。 |
| @@ -503,6 +504,7 @@ T3 sync S->MTE2 | |||
| 503 | `DSB`和流水同步只处理访问完成顺序和执行先后关系,保证内存一致性,不负责写回或失效DCache副本。如果Scalar写GM经过DCache,或者后续读取路径可能命中旧Cache副本,还需要参考[缓存一致性](cache_coherence.md)处理DCache相关问题。 | 504 | `DSB`和流水同步只处理访问完成顺序和执行先后关系,保证内存一致性,不负责写回或失效DCache副本。如果Scalar写GM经过DCache,或者后续读取路径可能命中旧Cache副本,还需要参考[缓存一致性](cache_coherence.md)处理DCache相关问题。 |
| 504 | 505 | ||
| 505 | <!-- npu="950" id11 --> | 506 | <!-- npu="950" id11 --> |
| 507 | + | ||
| 506 | ### SIMT内存一致性 | 508 | ### SIMT内存一致性 |
| 507 | 509 | ||
| 508 | SIMT内存一致性需要区分线程内和线程间: | 510 | SIMT内存一致性需要区分线程内和线程间: |
| @@ -52,6 +52,7 @@ Cache刷新机制示意图如下图所示: | |||
| 52 | | [AscendC::GetBlockNum()](../../../../api/SIMD-API/basic_api/tool_interface/system_resources_and_variables/GetBlockNum.md) | 获取当前任务配置的核数 | | 52 | | [AscendC::GetBlockNum()](../../../../api/SIMD-API/basic_api/tool_interface/system_resources_and_variables/GetBlockNum.md) | 获取当前任务配置的核数 | |
| 53 | 53 | ||
| 54 | <!-- npu="A3,910b" id1 --> | 54 | <!-- npu="A3,910b" id1 --> |
| 55 | + | ||
| 55 | ## TPipe析构约束 | 56 | ## TPipe析构约束 |
| 56 | 57 | ||
| 57 | 针对Atlas A2系列产品、Atlas A3系列产品,在GE入图及npugraph_ex后端aclnn调用场景,子算子TPipe对象析构([TPipe::Destroy](../../../../api/SIMD-API/basic_api/resource_management/TPipe/Destroy.md))接口内部的`AscendC::PipeBarrier<PIPE_ALL>()`指令会被去除,如果算子内部使用了多个TPipe对象或手动调用Destroy函数时开发者需自行保障TPipe对象间流水的同步。 | 58 | 针对Atlas A2系列产品、Atlas A3系列产品,在GE入图及npugraph_ex后端aclnn调用场景,子算子TPipe对象析构([TPipe::Destroy](../../../../api/SIMD-API/basic_api/resource_management/TPipe/Destroy.md))接口内部的`AscendC::PipeBarrier<PIPE_ALL>()`指令会被去除,如果算子内部使用了多个TPipe对象或手动调用Destroy函数时开发者需自行保障TPipe对象间流水的同步。 |
| @@ -1,4 +1,5 @@ | |||
| 1 | # 异步执行 | 1 | # 异步执行 |
| 2 | + | ||
| 2 | 当开发者完成一个核函数(Kernel)的编写后,需要通过特定的下发/启动语法将其提交到指定的Stream(计算流)上执行。例如: | 3 | 当开发者完成一个核函数(Kernel)的编写后,需要通过特定的下发/启动语法将其提交到指定的Stream(计算流)上执行。例如: |
| 3 | ```c++ | 4 | ```c++ |
| 4 | kernel<<<numBlocks, ubufDynSize, stream>>>(参数列表); | 5 | kernel<<<numBlocks, ubufDynSize, stream>>>(参数列表); |
| @@ -22,6 +23,7 @@ | |||
| 22 | 在这个过程中我们提到了Stream创建与销毁,内存申请与拷贝,异步调用与同步等待。在本节的其余部分,我们将解释这些CANN Runtime的元素和对应的API。 | 23 | 在这个过程中我们提到了Stream创建与销毁,内存申请与拷贝,异步调用与同步等待。在本节的其余部分,我们将解释这些CANN Runtime的元素和对应的API。 |
| 23 | 24 | ||
| 24 | ## Stream管理 | 25 | ## Stream管理 |
| 26 | + | ||
| 25 | Stream(计算流)本质上是一个有序的任务队列,为开发者提供了一种表示“先序执行”的抽象机制,程序可向队列中提交各类操作,例如内存拷贝、核函数(Kernel)下发等,所有任务将按入队顺序依次执行。单个计算流内,队列头部任务优先执行,执行完成后自动出队;后续队列任务依次前移,等待调度执行。同一个计算流中的任务具备串行执行特性,严格遵循入队先后顺序运行。 | 27 | Stream(计算流)本质上是一个有序的任务队列,为开发者提供了一种表示“先序执行”的抽象机制,程序可向队列中提交各类操作,例如内存拷贝、核函数(Kernel)下发等,所有任务将按入队顺序依次执行。单个计算流内,队列头部任务优先执行,执行完成后自动出队;后续队列任务依次前移,等待调度执行。同一个计算流中的任务具备串行执行特性,严格遵循入队先后顺序运行。 |
| 26 | 28 | ||
| 27 | 应用程序可同时创建并使用多个计算流。多流场景下,运行时会根据AI处理器的硬件资源占用状态,从存有待处理任务的计算流中择优调度任务执行。开发者可为计算流配置优先级,该优先级将作为运行时调度的参考依据,用以调整任务调度策略,但无法强制保证固定的执行顺序。 | 29 | 应用程序可同时创建并使用多个计算流。多流场景下,运行时会根据AI处理器的硬件资源占用状态,从存有待处理任务的计算流中择优调度任务执行。开发者可为计算流配置优先级,该优先级将作为运行时调度的参考依据,用以调整任务调度策略,但无法强制保证固定的执行顺序。 |
| @@ -37,6 +39,7 @@ CANN Runtime内置默认计算流,所有未显式指定计算流的运算操 | |||
| 37 | - **指定Stream同步**:`aclrtSynchronizeStream(stream)`。 | 39 | - **指定Stream同步**:`aclrtSynchronizeStream(stream)`。 |
| 38 | 40 | ||
| 39 | ## Memory(内存)管理 | 41 | ## Memory(内存)管理 |
| 42 | + | ||
| 40 | 在异构计算架构中,系统由主机(Host)和设备(Device)组成。Host和Device各自拥有独立的内存,Host内存是指AI处理器所在服务器的主机内存(即CPU内存),而Device内存则是指AI处理器自带的设备内存。 | 43 | 在异构计算架构中,系统由主机(Host)和设备(Device)组成。Host和Device各自拥有独立的内存,Host内存是指AI处理器所在服务器的主机内存(即CPU内存),而Device内存则是指AI处理器自带的设备内存。 |
| 41 | 44 | ||
| 42 | 内存管理中要做好的两件事是: | 45 | 内存管理中要做好的两件事是: |
| @@ -44,6 +47,7 @@ CANN Runtime内置默认计算流,所有未显式指定计算流的运算操 | |||
| 44 | 2. **高效访问内存**:算子在Device上执行过程中,访问Device上的Device内存数据性能更高。为此,Runtime提供了Host与Device之间互相拷贝内存的接口,支持同步和异步方式,例如aclrtMemcpy和aclrtMemcpyAsync等,以便开发者更好地规划数据的存储与访问。 | 47 | 2. **高效访问内存**:算子在Device上执行过程中,访问Device上的Device内存数据性能更高。为此,Runtime提供了Host与Device之间互相拷贝内存的接口,支持同步和异步方式,例如aclrtMemcpy和aclrtMemcpyAsync等,以便开发者更好地规划数据的存储与访问。 |
| 45 | 48 | ||
| 46 | ## 异步调用 | 49 | ## 异步调用 |
| 50 | + | ||
| 47 | 为了能够更好的发挥CPU和AI处理器的硬件利用率,CANN Runtime遵循“下发即返回”的异步执行策略,使Host在提交H2D/D2H拷贝或核函数(Kernel)计算任务后立即继续执行后续逻辑,从而让主机侧调度、设备侧计算、主机与设备之间的数据传输尽可能重叠执行,隐藏传输和调度开销,提高端到端吞吐率。 | 51 | 为了能够更好的发挥CPU和AI处理器的硬件利用率,CANN Runtime遵循“下发即返回”的异步执行策略,使Host在提交H2D/D2H拷贝或核函数(Kernel)计算任务后立即继续执行后续逻辑,从而让主机侧调度、设备侧计算、主机与设备之间的数据传输尽可能重叠执行,隐藏传输和调度开销,提高端到端吞吐率。 |
| 48 | 52 | ||
| 49 | 典型<<<\>\>\>异步调用的场景是:将主机与设备计算操作重叠执行,从而提升主机侧与设备侧计算资源利用率。 | 53 | 典型<<<\>\>\>异步调用的场景是:将主机与设备计算操作重叠执行,从而提升主机侧与设备侧计算资源利用率。 |
| @@ -56,6 +60,7 @@ CANN Runtime内置默认计算流,所有未显式指定计算流的运算操 | |||
| 56 | 60 | ||
| 57 | 61 | ||
| 58 | ## 同步等待 | 62 | ## 同步等待 |
| 63 | + | ||
| 59 | 核函数(Kernel)的调用是异步的,在核函数(Kernel)调用结束之后,控制权立刻返回给主机端,需要在host等待核函数(Kernel)的执行完成,可以通过以下接口强制Host程序等待核函数(Kernel)执行完毕: | 64 | 核函数(Kernel)的调用是异步的,在核函数(Kernel)调用结束之后,控制权立刻返回给主机端,需要在host等待核函数(Kernel)的执行完成,可以通过以下接口强制Host程序等待核函数(Kernel)执行完毕: |
| 60 | |同步接口|接口描述| | 65 | |同步接口|接口描述| |
| 61 | |-|-| | 66 | |-|-| |
| @@ -63,4 +68,5 @@ CANN Runtime内置默认计算流,所有未显式指定计算流的运算操 | |||
| 63 | |`aclrtSynchronizeStream()` |阻塞Host侧当前线程直到指定Stream中的所有操作都已完成。 | | 68 | |`aclrtSynchronizeStream()` |阻塞Host侧当前线程直到指定Stream中的所有操作都已完成。 | |
| 64 | 69 | ||
| 65 | ## 更多的Runtime高级特性 | 70 | ## 更多的Runtime高级特性 |
| 71 | + | ||
| 66 | 更多的Runtime编程方式及接口,可以参考[《应用开发(C&C++)》](https://hiascend.com/document/redirect/CannCommunityadev)。 | 72 | 更多的Runtime编程方式及接口,可以参考[《应用开发(C&C++)》](https://hiascend.com/document/redirect/CannCommunityadev)。 |
| @@ -1,7 +1,9 @@ | |||
| 1 | # AI Core编译基本用法<a name="section229217121411"></a> | 1 | # AI Core编译基本用法<a name="section229217121411"></a> |
| 2 | + | ||
| 2 | 当开发者完成一个核函数(Kernel)的编写,并在Host侧通过<<<\>\>\>方式完成核函数(Kernel)的启动调用后,就需要进行算子源码编译与算子运行,接下来我们介绍通过bisheng编译器完成算子编译的基本用法。 | 3 | 当开发者完成一个核函数(Kernel)的编写,并在Host侧通过<<<\>\>\>方式完成核函数(Kernel)的启动调用后,就需要进行算子源码编译与算子运行,接下来我们介绍通过bisheng编译器完成算子编译的基本用法。 |
| 3 | 4 | ||
| 4 | ## AI Core SIMD编译 | 5 | ## AI Core SIMD编译 |
| 6 | + | ||
| 5 | 使用bisheng编译Ascend C源文件的基本命令如下,其中--npu-arch=dav-\<npu architecture\>用于指定AI处理器架构版本: | 7 | 使用bisheng编译Ascend C源文件的基本命令如下,其中--npu-arch=dav-\<npu architecture\>用于指定AI处理器架构版本: |
| 6 | ```shell | 8 | ```shell |
| 7 | bisheng <source_file>.asc -o <output_file> --npu-arch=dav-<npu architecture> | 9 | bisheng <source_file>.asc -o <output_file> --npu-arch=dav-<npu architecture> |
| @@ -336,6 +338,7 @@ add_executable(demo | |||
| 336 | | libascendcl.so | acl相关接口库。 | | 338 | | libascendcl.so | acl相关接口库。 | |
| 337 | 339 | ||
| 338 | ### 高阶API常用链接库 | 340 | ### 高阶API常用链接库 |
| 341 | + | ||
| 339 | 在使用高阶API时,必须链接以下库,因为这些库是高阶API功能所依赖的。在其他场景下,可以根据具体需求选择是否链接这些库。 | 342 | 在使用高阶API时,必须链接以下库,因为这些库是高阶API功能所依赖的。在其他场景下,可以根据具体需求选择是否链接这些库。 |
| 340 | 343 | ||
| 341 | |链接库名称|作用描述|使用场景|动态库路径| | 344 | |链接库名称|作用描述|使用场景|动态库路径| |
| @@ -90,11 +90,14 @@ msDebug是一款面向昇腾设备的算子调试工具,用于调试NPU侧运 | |||
| 90 | ### msdebug调试进程 | 90 | ### msdebug调试进程 |
| 91 | 91 | ||
| 92 | #### 调试程序编译 | 92 | #### 调试程序编译 |
| 93 | + | ||
| 93 | ```shell | 94 | ```shell |
| 94 | // bisheng编译时增加debug命令行 | 95 | // bisheng编译时增加debug命令行 |
| 95 | bisheng add_custom.asc -o add_custom -O0 -g | 96 | bisheng add_custom.asc -o add_custom -O0 -g |
| 96 | ``` | 97 | ``` |
| 98 | + | ||
| 97 | #### 调试程序运行 | 99 | #### 调试程序运行 |
| 100 | + | ||
| 98 | ```shell | 101 | ```shell |
| 99 | // 使用msdebug进行调试 | 102 | // 使用msdebug进行调试 |
| 100 | $ msdebug ./add_custom | 103 | $ msdebug ./add_custom |
| @@ -110,12 +113,14 @@ Breakpoint 1: where = device_debugdata`_ZN17MatmulLeakyKernelIDhDhffE7CopyOutEj_ | |||
| 110 | ``` | 113 | ``` |
| 111 | 114 | ||
| 112 | #### 断点设置 | 115 | #### 断点设置 |
| 116 | + | ||
| 113 | ```shell | 117 | ```shell |
| 114 | (msdebug) b matmul_leakyrelu_kernel.cpp:114 | 118 | (msdebug) b matmul_leakyrelu_kernel.cpp:114 |
| 115 | Breakpoint 1: where = device_debugdata`_ZN17MatmulLeakyKernelIDhDhffE7CopyOutEj_mix_aiv + 240 at matmul_leakyrelu_kernel.cpp:114:14, address = 0x000000000000ff88 | 119 | Breakpoint 1: where = device_debugdata`_ZN17MatmulLeakyKernelIDhDhffE7CopyOutEj_mix_aiv + 240 at matmul_leakyrelu_kernel.cpp:114:14, address = 0x000000000000ff88 |
| 116 | ``` | 120 | ``` |
| 117 | 121 | ||
| 118 | #### 内存与变量打印 | 122 | #### 内存与变量打印 |
| 123 | + | ||
| 119 | ```shell | 124 | ```shell |
| 120 | # 打印LocalTensor | 125 | # 打印LocalTensor |
| 121 | (msdebug) p reluOutLocal | 126 | (msdebug) p reluOutLocal |
| @@ -134,6 +139,7 @@ Breakpoint 1: where = device_debugdata`_ZN17MatmulLeakyKernelIDhDhffE7CopyOutEj_ | |||
| 134 | ``` | 139 | ``` |
| 135 | 140 | ||
| 136 | #### 单步调试 | 141 | #### 单步调试 |
| 142 | + | ||
| 137 | ```shell | 143 | ```shell |
| 138 | (msdebug) s | 144 | (msdebug) s |
| 139 | Process 177943 stopped | 145 | Process 177943 stopped |
| @@ -148,6 +154,7 @@ Process 177943 stopped | |||
| 148 | ``` | 154 | ``` |
| 149 | 155 | ||
| 150 | #### 调试信息展示 | 156 | #### 调试信息展示 |
| 157 | + | ||
| 151 | ```shell | 158 | ```shell |
| 152 | (msdebug) ascend info cores | 159 | (msdebug) ascend info cores |
| 153 | CoreId Type Device Stream Task Block PC stop reason | 160 | CoreId Type Device Stream Task Block PC stop reason |
| @@ -157,6 +164,7 @@ Process 177943 stopped | |||
| 157 | ``` | 164 | ``` |
| 158 | 165 | ||
| 159 | ### 解析异常算子dump文件 | 166 | ### 解析异常算子dump文件 |
| 167 | + | ||
| 160 | 通过环境变量开启算子异常时Dump出Core文件。 | 168 | 通过环境变量开启算子异常时Dump出Core文件。 |
| 161 | ```shell | 169 | ```shell |
| 162 | # aic_err_detail_dump: 导出AI Core的内存存储、寄存器和调用栈信息。 | 170 | # aic_err_detail_dump: 导出AI Core的内存存储、寄存器和调用栈信息。 |
| @@ -123,6 +123,7 @@ kernel_name<<<block_num, dyn_ub_size, stream>>>(args...); | |||
| 123 | ## VF函数的asc\_vf\_call调用 | 123 | ## VF函数的asc\_vf\_call调用 |
| 124 | 124 | ||
| 125 | ### SIMT VF的asc\_vf\_call调用 | 125 | ### SIMT VF的asc\_vf\_call调用 |
| 126 | + | ||
| 126 | SIMD与SIMT混合编程以SIMD核函数(Kernel)作为Device侧入口,在核函数(Kernel)或`__aicore__`函数中通过`asc_vf_call`启动SIMT VF子任务,通过参数配置,启动指定数目的线程,执行指定的SIMT VF函数。其函数原型如下: | 127 | SIMD与SIMT混合编程以SIMD核函数(Kernel)作为Device侧入口,在核函数(Kernel)或`__aicore__`函数中通过`asc_vf_call`启动SIMT VF子任务,通过参数配置,启动指定数目的线程,执行指定的SIMT VF函数。其函数原型如下: |
| 127 | 128 | ||
| 128 | ```cpp | 129 | ```cpp |
| @@ -63,6 +63,7 @@ Cube单元采用分块计算逻辑,硬件最小计算粒度为分形块,可 | |||
| 63 | ND格式是通用的N维张量格式,数据在内存中连续线性存放,通常存在于`Global Memory (GM)`中。在进行矩阵运算前,通常需要将其转换为Nz格式以适配Cube计算单元。 | 63 | ND格式是通用的N维张量格式,数据在内存中连续线性存放,通常存在于`Global Memory (GM)`中。在进行矩阵运算前,通常需要将其转换为Nz格式以适配Cube计算单元。 |
| 64 | 64 | ||
| 65 | #### Nz 格式 | 65 | #### Nz 格式 |
| 66 | + | ||
| 66 | Nz格式主要用于L1 Buffer和L0C Buffer中存放数据。针对[NPU架构版本3510](../../../language_extension/simd_builtin_keywords.md),L0A Buffer也采用Nz分形格式。该格式采用大N(外部列主序)+ 小z(内部行主序)的方式排布。 | 67 | Nz格式主要用于L1 Buffer和L0C Buffer中存放数据。针对[NPU架构版本3510](../../../language_extension/simd_builtin_keywords.md),L0A Buffer也采用Nz分形格式。该格式采用大N(外部列主序)+ 小z(内部行主序)的方式排布。 |
| 67 | 68 | ||
| 68 | <img src="../../../../figures/nz_format.png" alt="Nz数据排布格式" width="400"/> | 69 | <img src="../../../../figures/nz_format.png" alt="Nz数据排布格式" width="400"/> |