已合并
add Add/RmsNormDynamicMxQuant op_api #3176
刘琦创建于 3月25日
add Add/RmsNormDynamicMxQuant op_api #3176
已合并
刘琦创建于 3月25日
29 个文件变更+745-88
Mnorm/add_rms_norm_dynamic_mx_quant/README.md+10-10
@@ -26,7 +26,7 @@
26 y = \operatorname{RmsNorm}(x)=\frac{x}{\operatorname{Rms}(\mathbf{x})}\cdot gamma+beta, \quad \text { where } \operatorname{Rms}(\mathbf{x})=\sqrt{\frac{1}{n} \sum_{i=1}^n x_i^2+epsilon}26 y = \operatorname{RmsNorm}(x)=\frac{x}{\operatorname{Rms}(\mathbf{x})}\cdot gamma+beta, \quad \text { where } \operatorname{Rms}(\mathbf{x})=\sqrt{\frac{1}{n} \sum_{i=1}^n x_i^2+epsilon}
27 $$27 $$
28 28 
29-scaleAlg为0时:29+scale_alg为0时:
30 - 将RmsNorm输出y在尾轴维度上按k = 32个数分组,一组k个数 $\{\{V_i\}_{i=1}^{k}\}$ 动态量化为 $\{mxscale,\{P_i\}_{i=1}^{k}\}$30 - 将RmsNorm输出y在尾轴维度上按k = 32个数分组,一组k个数 $\{\{V_i\}_{i=1}^{k}\}$ 动态量化为 $\{mxscale,\{P_i\}_{i=1}^{k}\}$
31 $$31 $$
32 shared\_exp = floor(log_2(max_i(|V_i|))) - emax 32 shared\_exp = floor(log_2(max_i(|V_i|))) - emax
@@ -48,7 +48,7 @@
48 | FLOAT8_E4M3FN | 8 |48 | FLOAT8_E4M3FN | 8 |
49 | FLOAT8_E5M2 | 15 |49 | FLOAT8_E5M2 | 15 |
50 50 
51-scaleAlg为1时,只涉及FP8类型:51+scale_alg为1时,只涉及FP8类型:
52 - 将长向量按块分,每块长度为k,对每块单独计算一个块缩放因子$S_{fp32}^b$,再把块内所有元素用同一个$S_{fp32}^b$映射到目标低精度类型FP8。52 - 将长向量按块分,每块长度为k,对每块单独计算一个块缩放因子$S_{fp32}^b$,再把块内所有元素用同一个$S_{fp32}^b$映射到目标低精度类型FP8。
53 - 找到该块中数值的最大绝对值:53 - 找到该块中数值的最大绝对值:
54 $$54 $$
@@ -124,28 +124,28 @@
124 <tr>124 <tr>
125 <td>scale_alg</td>125 <td>scale_alg</td>
126 <td>可选属性</td>126 <td>可选属性</td>
127- <td><ul><li>表示mxscaleOut的计算方法,对应公式中的scaleAlg。</li><li>支持取值0和1,取值为0表示Open Compute Project(OCP)实现,取值为1表示cuBLAS实现。当dstType为FLOAT4_E2M1/FLOAT4_E1M2时仅支持取值为0。</li><li>默认值为0。</li></ul></td>127+ <td><ul><li>表示mxscale的计算方法,对应公式中的scale_alg。</li><li>支持取值0和1,取值为0表示Open Compute Project(OCP)实现,取值为1表示cuBLAS实现。当dst_type为FLOAT4_E2M1/FLOAT4_E1M2时仅支持取值为0。</li><li>默认值为0。</li></ul></td>
128 <td>INT64</td>128 <td>INT64</td>
129 <td>-</td>129 <td>-</td>
130 </tr>130 </tr>
131 <tr>131 <tr>
132 <td>round_mode</td>132 <td>round_mode</td>
133 <td>可选属性</td>133 <td>可选属性</td>
134- <td><ul><li>表示数据转换的模式,对应公式中的round_mode。</li><li>当dstType为40/41时,支持{"rint", "floor", "round"}。</li><li>当dstType为36/35时,仅支持{"rint"}。</li><li>默认值为"rint"。</li></ul></td>134+ <td><ul><li>表示数据转换的模式,对应公式中的round_mode。</li><li>当dst_type为40/41时,支持{"rint", "floor", "round"}。</li><li>当dst_type为36/35时,仅支持{"rint"}。</li><li>默认值为"rint"。</li></ul></td>
135 <td>STRING</td>135 <td>STRING</td>
136 <td>-</td>136 <td>-</td>
137 </tr>137 </tr>
138 <tr>138 <tr>
139 <td>dst_type</td>139 <td>dst_type</td>
140 <td>可选属性</td>140 <td>可选属性</td>
141- <td><ul><li>表示指定数据转换后yOut的类型,对应公式中的DType。</li><li>输入范围为{35, 36, 40, 41},分别对应{FLOAT8_E5M2, FLOAT8_E4M3FN, FLOAT4_E2M1, FLOAT4_E1M2}。</li><li>默认值为40。</li></ul></td>141+ <td><ul><li>表示指定数据转换后y的类型,对应公式中的DType。</li><li>输入范围为{35, 36, 40, 41},分别对应{FLOAT8_E5M2, FLOAT8_E4M3FN, FLOAT4_E2M1, FLOAT4_E1M2}。</li><li>默认值为40。</li></ul></td>
142 <td>INT64</td>142 <td>INT64</td>
143 <td>-</td>143 <td>-</td>
144 </tr>144 </tr>
145 <tr>145 <tr>
146 <td>output_rstd</td>146 <td>output_rstd</td>
147 <td>可选属性</td>147 <td>可选属性</td>
148- <td><ul><li>表示指定是否输出有效的rstdOut。</li><li>支持True和False。</li><li>默认值为False。</li><li>当outputRstd为False时,rstdOut最终输出空Tensor,此时rstdOut为无效占位输出。</li></ul></td>148+ <td><ul><li>表示指定是否输出有效的rstd_out。</li><li>支持True和False。</li><li>默认值为False。</li><li>当output_rstd为False时,rstd为无效占位输出。</li></ul></td>
149 <td>BOOL</td>149 <td>BOOL</td>
150 <td>-</td>150 <td>-</td>
151 </tr>151 </tr>
@@ -173,7 +173,7 @@
173 <tr>173 <tr>
174 <td>rstd</td>174 <td>rstd</td>
175 <td>输出</td>175 <td>输出</td>
176- <td><ul><li>表示归一化后的标准差的倒数,对应公式中Rms(x)的倒数。</li><li>当output_rstd为True时,shape与入参x1的shape前几维保持一致,前几维指x1的维度减去gamma的维度,表示不需要norm的维度。</li><li>当output_rstd为False时,rstd_out输出空Tensor。</li></ul></td>176+ <td><ul><li>表示归一化后的标准差的倒数,对应公式中Rms(x)的倒数。</li><li>当output_rstd为True时,shape与入参x1的shape前几维保持一致,前几维指x1的维度减去gamma的维度,表示不需要norm的维度。</li><li>当output_rstd为False时,rstd为无效占位输出。</li></ul></td>
177 <td>FLOAT32</td>177 <td>FLOAT32</td>
178 <td>ND</td>178 <td>ND</td>
179 </tr>179 </tr>
@@ -189,13 +189,13 @@
189 - mxscale.shape[-1] = 2。189 - mxscale.shape[-1] = 2。
190 - 其他维度与输入x1一致。190 - 其他维度与输入x1一致。
191 191 
192-- 当输出yOut的数据类型为FLOAT4_E2M1或FLOAT4_E1M2,x1尾轴的值必须为偶数。192+- 当输出y的数据类型为FLOAT4_E2M1或FLOAT4_E1M2,x1尾轴的值必须为偶数。
193 193 
194- 输入gamma、可选输入beta的数据类型只能和x1的数据类型保持一致或者为FLOAT32。194- 输入gamma、可选输入beta的数据类型只能和x1的数据类型保持一致或者为FLOAT32。
195 195 
196- **边界值场景说明**196- **边界值场景说明**
197- - 当输入是Inf时:1、输出yOut为0;2、输出xOut为Inf;3、输出mxscaleOut为255,偶数pad填充值为0;4、输出rstdOut为0。197+ - 当输入是Inf时:1、输出y为0;2、输出x为Inf;3、输出mxscale为255,偶数pad填充值为0;4、输出rstd为0。
198- - 当输入是NaN时:1、输出yOut为0;2、输出xOut为Nan;3、输出mxscaleOut为255,偶数pad填充值为0;4、输出rstdOut为NaN。198+ - 当输入是NaN时:1、输出y为0;2、输出x为Nan;3、输出mxscale为255,偶数pad填充值为0;4、输出rstd为NaN。
199 199 
200## 调用说明200## 调用说明
201 201 
Mnorm/add_rms_norm_dynamic_mx_quant/docs/aclnnAddRmsNormDynamicMxQuant.md+23-21
@@ -80,7 +80,7 @@ aclnnStatus aclnnAddRmsNormDynamicMxQuantGetWorkspaceSize(
80 const aclTensor *beta,80 const aclTensor *beta,
81 double epsilon,81 double epsilon,
82 int64_t scaleAlg,82 int64_t scaleAlg,
83- char *roundModeOptional,83+ char *roundMode,
84 int64_t dstType,84 int64_t dstType,
85 bool outputRstd,85 bool outputRstd,
86 aclTensor *yOut,86 aclTensor *yOut,
@@ -129,7 +129,7 @@ aclnnStatus aclnnAddRmsNormDynamicMxQuant(
129 <td>x1(aclTensor*)</td>129 <td>x1(aclTensor*)</td>
130 <td>输入</td>130 <td>输入</td>
131 <td>表示标准化过程中的源数据张量。对应公式中的x1。</td>131 <td>表示标准化过程中的源数据张量。对应公式中的x1。</td>
132- <td><ul><li>不支持空Tensor。</li></ul></td>132+ <td><ul><li>不支持空Tensor。</li><li>具体约束详见约束说明。</li></ul></td>
133 <td>FLOAT16、BFLOAT16</td>133 <td>FLOAT16、BFLOAT16</td>
134 <td>ND</td>134 <td>ND</td>
135 <td>1-7</td>135 <td>1-7</td>
@@ -149,7 +149,7 @@ aclnnStatus aclnnAddRmsNormDynamicMxQuant(
149 <td>gamma(aclTensor*)</td>149 <td>gamma(aclTensor*)</td>
150 <td>输入</td>150 <td>输入</td>
151 <td>表示标准化过程中的权重张量。对应公式中的gamma。</td>151 <td>表示标准化过程中的权重张量。对应公式中的gamma。</td>
152- <td><ul><li>不支持空Tensor。</li><li>shape只能为一维,需要与x1最后一维维度匹配。</li></ul></td>152+ <td><ul><li>不支持空Tensor。</li><li>shape只能为一维,需要与x1最后一维维度匹配。</li><li>数据类型默认与输入x1一致;若不一致,则显示设为FLOAT32。</li></ul></td>
153 <td>FLOAT16、BFLOAT16、FLOAT32</td>153 <td>FLOAT16、BFLOAT16、FLOAT32</td>
154 <td>ND</td>154 <td>ND</td>
155 <td>1</td>155 <td>1</td>
@@ -209,7 +209,7 @@ aclnnStatus aclnnAddRmsNormDynamicMxQuant(
209 <td>outputRstd(bool)</td>209 <td>outputRstd(bool)</td>
210 <td>输入</td>210 <td>输入</td>
211 <td>表示指定是否输出有效的rstdOut。</td>211 <td>表示指定是否输出有效的rstdOut。</td>
212- <td><ul><li>支持True和False。</li><li>当outputRstd为False时,rstdOut最终输出空Tensor,此时rstdOut为无效占位输出。</li></ul></td>212+ <td><ul><li>支持True和False。</li><li>当outputRstd为False时,rstdOut为无效输出。</li></ul></td>
213 <td>-</td>213 <td>-</td>
214 <td>-</td>214 <td>-</td>
215 <td>-</td>215 <td>-</td>
@@ -219,7 +219,7 @@ aclnnStatus aclnnAddRmsNormDynamicMxQuant(
219 <td>yOut(aclTensor*)</td>219 <td>yOut(aclTensor*)</td>
220 <td>输出</td>220 <td>输出</td>
221 <td>表示归一化并量化后的结果,对应公式中的Pi和di。</td>221 <td>表示归一化并量化后的结果,对应公式中的Pi和di。</td>
222- <td><ul><li>不支持空Tensor。</li><li>shape需要与输入x1一致。</li></ul></td>222+ <td><ul><li>不支持空Tensor。</li><li>shape需要与输入x1一致。</li><li>数据类型需要与dstType保持一致。</li></ul></td>
223 <td>FLOAT4_E2M1、FLOAT4_E1M2、FLOAT8_E4M3FN、FLOAT8_E5M2</td>223 <td>FLOAT4_E2M1、FLOAT4_E1M2、FLOAT8_E4M3FN、FLOAT8_E5M2</td>
224 <td>ND</td>224 <td>ND</td>
225 <td>1-7</td>225 <td>1-7</td>
@@ -239,7 +239,7 @@ aclnnStatus aclnnAddRmsNormDynamicMxQuant(
239 <td>mxscaleOut(aclTensor*)</td>239 <td>mxscaleOut(aclTensor*)</td>
240 <td>输出</td>240 <td>输出</td>
241 <td>表示每个分组对应的量化尺度,对应公式中的mxscale和Sb。</td>241 <td>表示每个分组对应的量化尺度,对应公式中的mxscale和Sb。</td>
242- <td><ul><li>不支持空Tensor。</li><li>shape在尾轴上为x对应值除以blocksize=32向上取整,并对其进行偶数pad,pad填充值为0,具体计算过程见约束说明。其余维度与入参x1的shape前几维保持一致,前几维指x1的维度减去gamma的维度,表示不需要norm的维度。</li></ul></td>242+ <td><ul><li>不支持空Tensor。</li><li>shape在尾轴上为x对应值除以blocksize=32向上取整,并对其进行偶数pad,pad填充值为0。</li><li>其余维度与入参x1的shape前几维保持一致,前几维指x1的维度减去gamma的维度,表示不需要norm的维度。</li><li>具体计算过程见约束说明。</li></ul></td>
243 <td>FLOAT8_E8M0</td>243 <td>FLOAT8_E8M0</td>
244 <td>ND</td>244 <td>ND</td>
245 <td>2-8</td>245 <td>2-8</td>
@@ -249,7 +249,7 @@ aclnnStatus aclnnAddRmsNormDynamicMxQuant(
249 <td>rstdOut(aclTensor*)</td>249 <td>rstdOut(aclTensor*)</td>
250 <td>输出</td>250 <td>输出</td>
251 <td>表示归一化后的标准差的倒数。对应公式中Rms(x)的倒数。</td>251 <td>表示归一化后的标准差的倒数。对应公式中Rms(x)的倒数。</td>
252- <td><ul><li>支持空Tensor。</li><li>当outputRstd为True时,shape与入参x1的shape前几维保持一致,前几维指x1的维度减去gamma的维度,表示不需要norm的维度。</li><li>当outputRstd为False时,rstdOut输出空Tensor。</li></ul></td>252+ <td><ul><li>支持空Tensor。</li><li>当outputRstd为True时,shape与入参x1的shape前几维保持一致,前几维指x1的维度减去gamma的维度,表示不需要norm的维度。</li><li>当outputRstd为False时,rstdOut为无效输出。</li></ul></td>
253 <td>FLOAT32</td>253 <td>FLOAT32</td>
254 <td>ND</td>254 <td>ND</td>
255 <td>1-7</td>255 <td>1-7</td>
@@ -298,36 +298,38 @@ aclnnStatus aclnnAddRmsNormDynamicMxQuant(
298 </thead>298 </thead>
299 <tbody>299 <tbody>
300 <tr>300 <tr>
301- <td>ACLNN_ERR_PARAM_NULLPTR</td>301+ <td rowspan="2">ACLNN_ERR_PARAM_NULLPTR</td>
302- <td>161001</td>302+ <td rowspan="2">161001</td>
303- <td>传入的x1、x2、gamma、yOut、xOut、mxscaleOutrstdOut是空指针。</td>303+ <td>传入的x1、x2、gamma、yOut、xOut和mxscaleOut是空指针。</td>
304 </tr>304 </tr>
305 <tr>305 <tr>
306- <td>ACLNN_ERR_PARAM_INVALID</td>306+ <td>当outputRstd为True时,传入rstdOut是空指针。</td>
307- <td>161002</td>
308- <td>输入或输出的数据类型不在支持的范围之内。</td>
309 </tr>307 </tr>
310 <tr>308 <tr>
311- <td rowspan="9">ACLNN_ERR_INNER_TILING_ERROR</td>309+ <td rowspan="8">ACLNN_ERR_INNER_TILING_ERROR</td>
312- <td rowspan="9">561002</td>310+ <td rowspan="8">561002</td>
311+ <td>输入或输出参数的维度数和数据类型不在范围之内,dstType和yOut的数据类型不匹配。</td>
313 </tr>312 </tr>
314 <tr>313 <tr>
315- <td>scaleAlg不是0或1,roundModeOptional(非空时)不是 {rint, floor, round}。</td>314+ <td>输入x1、x2和输出yOut、xOut的shape不是完全相同的shape。</td>
316 </tr>315 </tr>
317 <tr>316 <tr>
318- <td>dstType fp8 时roundModeOptional是 rint。</td>317+ <td>gamma、beta(若存在)的shape不是完全相同的shape,或二者的维度数不1或轴长等于x1的尾轴大小,或者类型不相同。</td>
319 </tr>318 </tr>
320 <tr>319 <tr>
321- <td>输入x1、输出yOutshape是完全相同的shape。</td>320+ <td>gamma的维度和x1的需要做norm的维度不相同,或rstdOut维度和x1的不需要norm的维度不相同,或rstdOut对应x1归一化维度的轴长不为1。</td>
322 </tr>321 </tr>
323 <tr>322 <tr>
324- <td>mxscaleOut的维度数等于输入x1的维度数+1。</td>323+ <td>scaleAlg是0或1,roundMode不是 {rint, floor, round}。</td>
325 </tr>324 </tr>
326 <tr>325 <tr>
327- <td>gamma、beta(若存在)的shape不是完全相同的shape或者类型相同。</td>326+ <td>dstType为 fp8 时roundMode是 rint。</td>
328 </tr>327 </tr>
329 <tr>328 <tr>
330- <td>gamma的维度和x1的需要作norm的维度不相同或rstdOut的维度和x1的需要norm的维度不相同,或x1的需要norm的维度数为1。</td>329+ <td>dstType为 fp4 时scaleAlg是0,或者输入x1的尾轴能被2整除。</td>
330+ </tr>
331+ <tr>
332+ <td>mxscaleOut的维度数不等于输入x1的维度数+1,或轴长不符合约束说明。</td>
331 </tr>333 </tr>
332 </tbody></table>334 </tbody></table>
333 335 
Mnorm/add_rms_norm_dynamic_mx_quant/op_host/CMakeLists.txt+1-1
@@ -9,4 +9,4 @@
9# -----------------------------------------------------------------------------------------------------------9# -----------------------------------------------------------------------------------------------------------
10 10 
11add_modules_sources(HOSTNAME ${OPHOST_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}11add_modules_sources(HOSTNAME ${OPHOST_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}
12- OPTYPE add_rms_norm_dynamic_mx_quant ACLNNTYPE aclnn DEPENDENCIES norm_common)12+ OPTYPE add_rms_norm_dynamic_mx_quant ACLNNTYPE aclnn_exclude DEPENDENCIES norm_common)
Anorm/add_rms_norm_dynamic_mx_quant/op_host/op_api/aclnn_add_rms_norm_dynamic_mx_quant.cpp+157-0
@@ -0,0 +1,157 @@
1+/**
2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+#include "aclnn/aclnn_base.h"
11+#include "op_api/op_api_def.h"
12+ 
13+#include "opdev/common_types.h"
14+#include "opdev/data_type_utils.h"
15+#include "opdev/op_executor.h"
16+#include "opdev/op_log.h"
17+#include "opdev/format_utils.h"
18+#include "opdev/tensor_view_utils.h"
19+#include "opdev/op_dfx.h"
20+#include "opdev/shape_utils.h"
21+#include "opdev/platform.h"
22+ 
23+#include "aclnn_kernels/common/op_error_check.h"
24+#include "aclnn_kernels/cast.h"
25+#include "aclnn_kernels/contiguous.h"
26+#include "op_api/aclnn_util.h"
27+ 
28+#include "add_rms_norm_dynamic_mx_quant.h"
29+#include "aclnn_add_rms_norm_dynamic_mx_quant.h"
30+ 
31+using namespace op;
32+#ifdef __cplusplus
33+extern "C" {
34+#endif
35+ 
36+constexpr int IDX_0 = 0;
37+constexpr int IDX_1 = 1;
38+constexpr int IDX_2 = 2;
39+constexpr int IDX_3 = 3;
40+ 
41+static bool CheckNotNull(
42+ const aclTensor* x1, const aclTensor* x2, const aclTensor* gamma, aclTensor* yOut, aclTensor* xOut,
43+ aclTensor* mxscaleOut, bool outputRstd, aclTensor* rstdOut)
44+{
45+ OP_CHECK_NULL(x1, return false);
46+ OP_CHECK_NULL(x2, return false);
47+ OP_CHECK_NULL(gamma, return false);
48+ // beta 是可选输入,不校验nullptr
49+ OP_CHECK_NULL(yOut, return false);
50+ OP_CHECK_NULL(xOut, return false);
51+ OP_CHECK_NULL(mxscaleOut, return false);
52+ // rstdOut 根据 outputRstd 决定是否校验
53+ if (outputRstd) {
54+ OP_CHECK_NULL(rstdOut, return false);
55+ }
56+ return true;
57+}
58+ 
59+static aclnnStatus ComputeAddRmsNormDynamicMxQuant(
60+ const aclTensor* x1, const aclTensor* x2, const aclTensor* gamma, const aclTensor* beta, double epsilon,
61+ int64_t scaleAlg, char* roundMode, int64_t dstType, bool outputRstd, aclTensor* yOut, aclTensor* xOut,
62+ aclTensor* mxscaleOut, aclTensor* rstdOut, aclOpExecutor* executor)
63+{
64+ // 创建输出Tensor
65+ aclTensor* y_output = executor->AllocTensor(yOut->GetViewShape(), yOut->GetDataType(), yOut->GetViewFormat());
66+ aclTensor* x_output = executor->AllocTensor(xOut->GetViewShape(), xOut->GetDataType(), xOut->GetViewFormat());
67+ aclTensor* mxscale_output =
68+ executor->AllocTensor(mxscaleOut->GetViewShape(), mxscaleOut->GetDataType(), mxscaleOut->GetViewFormat());
69+ aclTensor* rstd_output =
70+ (outputRstd) ?
71+ executor->AllocTensor(rstdOut->GetViewShape(), rstdOut->GetDataType(), rstdOut->GetViewFormat()) :
72+ executor->AllocTensor(op::Shape({0}), op::DataType::DT_FLOAT, op::Format::FORMAT_ND);
W
Wwangyu_ai4月8日

此条代码评论区间+69+72

可选场景能传空指针嘛?

likedislike
刘琦
刘琦
4月9日 评论:
73+ 
74+ auto addRmsNormDynamicMxQuantOuts = l0op::AddRmsNormDynamicMxQuant(
75+ x1, x2, gamma, beta, epsilon, scaleAlg, roundMode, dstType, outputRstd, y_output, x_output, mxscale_output,
76+ rstd_output, executor);
77+ 
78+ auto yComputeOut = std::get<IDX_0>(addRmsNormDynamicMxQuantOuts);
79+ auto xComputeOut = std::get<IDX_1>(addRmsNormDynamicMxQuantOuts);
80+ auto mxscaleComputeOut = std::get<IDX_2>(addRmsNormDynamicMxQuantOuts);
81+ auto rstdComputeOut = std::get<IDX_3>(addRmsNormDynamicMxQuantOuts);
82+ 
83+ // 校验输出不为空
84+ CHECK_RET(yComputeOut != nullptr, ACLNN_ERR_INNER_NULLPTR);
85+ CHECK_RET(xComputeOut != nullptr, ACLNN_ERR_INNER_NULLPTR);
86+ CHECK_RET(mxscaleComputeOut != nullptr, ACLNN_ERR_INNER_NULLPTR);
87+ 
88+ // 将结果拷贝到输出tensor
89+ auto viewCopyYResult = l0op::ViewCopy(yComputeOut, yOut, executor);
90+ CHECK_RET(viewCopyYResult != nullptr, ACLNN_ERR_INNER_NULLPTR);
91+ 
92+ auto viewCopyXResult = l0op::ViewCopy(xComputeOut, xOut, executor);
93+ CHECK_RET(viewCopyXResult != nullptr, ACLNN_ERR_INNER_NULLPTR);
94+ 
95+ auto viewCopyMxscaleResult = l0op::ViewCopy(mxscaleComputeOut, mxscaleOut, executor);
96+ CHECK_RET(viewCopyMxscaleResult != nullptr, ACLNN_ERR_INNER_NULLPTR);
97+ 
98+ if (outputRstd) {
99+ CHECK_RET(rstdComputeOut != nullptr, ACLNN_ERR_INNER_NULLPTR);
100+ auto viewCopyRstdResult = l0op::ViewCopy(rstdComputeOut, rstdOut, executor);
101+ CHECK_RET(viewCopyRstdResult != nullptr, ACLNN_ERR_INNER_NULLPTR);
102+ }
103+ 
104+ return ACLNN_SUCCESS;
105+}
106+ 
107+aclnnStatus aclnnAddRmsNormDynamicMxQuantGetWorkspaceSize(
108+ const aclTensor* x1, const aclTensor* x2, const aclTensor* gamma, const aclTensor* beta, double epsilon,
109+ int64_t scaleAlg, char* roundMode, int64_t dstType, bool outputRstd, aclTensor* yOut, aclTensor* xOut,
110+ aclTensor* mxscaleOut, aclTensor* rstdOut, uint64_t* workspaceSize, aclOpExecutor** executor)
111+{
112+ OP_LOGD("Enter aclnnAddRmsNormDynamicMxQuantGetWorkspaceSize.");
113+ L2_DFX_PHASE_1(
114+ aclnnAddRmsNormDynamicMxQuant, DFX_IN(x1, x2, gamma, beta, epsilon, scaleAlg, roundMode, dstType, outputRstd),
115+ DFX_OUT(yOut, xOut, mxscaleOut, rstdOut));
116+ 
117+ // 创建OpExecutor
118+ auto uniqueExecutor = CREATE_EXECUTOR();
119+ CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR);
120+ 
121+ // 检查必选输入/输出是否为空指针
122+ CHECK_RET(CheckNotNull(x1, x2, gamma, yOut, xOut, mxscaleOut, outputRstd, rstdOut), ACLNN_ERR_PARAM_NULLPTR);
123+ 
124+ // 固定写法,将输入转换成连续的tensor,可选输入不做判空校验
125+ auto x1Cont = l0op::Contiguous(x1, uniqueExecutor.get());
126+ auto x2Cont = l0op::Contiguous(x2, uniqueExecutor.get());
127+ auto gammaCont = l0op::Contiguous(gamma, uniqueExecutor.get());
128+ 
129+ CHECK_RET(x1Cont != nullptr, ACLNN_ERR_INNER_NULLPTR);
130+ CHECK_RET(x2Cont != nullptr, ACLNN_ERR_INNER_NULLPTR);
131+ CHECK_RET(gammaCont != nullptr, ACLNN_ERR_INNER_NULLPTR);
132+ 
133+ const aclTensor* betaCont = (beta == nullptr) ? nullptr : l0op::Contiguous(beta, uniqueExecutor.get());
134+ 
135+ auto ret = ComputeAddRmsNormDynamicMxQuant(
136+ x1Cont, x2Cont, gammaCont, betaCont, epsilon, scaleAlg, roundMode, dstType, outputRstd, yOut, xOut, mxscaleOut,
137+ rstdOut, uniqueExecutor.get());
138+ CHECK_RET(ret == ACLNN_SUCCESS, ret);
139+ 
140+ // 获取计算过程中需要使用的workspace大小
141+ *workspaceSize = uniqueExecutor->GetWorkspaceSize();
142+ uniqueExecutor.ReleaseTo(executor);
143+ OP_LOGD("Finish aclnnAddRmsNormDynamicMxQuantGetWorkspaceSize.");
144+ return ACLNN_SUCCESS;
145+}
146+ 
147+aclnnStatus aclnnAddRmsNormDynamicMxQuant(
148+ void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream)
149+{
150+ L2_DFX_PHASE_2(aclnnAddRmsNormDynamicMxQuant);
151+ // 固定写法,调用框架能力,完成计算
152+ return CommonOpExecutorRun(workspace, workspaceSize, executor, stream);
153+}
154+ 
155+#ifdef __cplusplus
156+}
157+#endif
Anorm/add_rms_norm_dynamic_mx_quant/op_host/op_api/aclnn_add_rms_norm_dynamic_mx_quant.h+97-0
@@ -0,0 +1,97 @@
1+/**
2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+#ifndef OP_API_INC_LEVEL2_ADD_RMS_NORM_DYNAMIC_MX_QUANT_H_
12+#define OP_API_INC_LEVEL2_ADD_RMS_NORM_DYNAMIC_MX_QUANT_H_
13+ 
14+#include "aclnn/aclnn_base.h"
15+#include "aclnn_util.h"
16+ 
17+#ifdef __cplusplus
18+extern "C" {
19+#endif
20+ 
21+/**
22+ * @brief aclnnAddRmsNormDynamicMxQuant的第一段接口,根据具体的计算流程,计算workspace大小。
23+ * @domain aclnn_ops_infer
24+ *
25+ * 算子功能:Add + RmsNorm + 量化计算的融合算子,将加法的计算结果做层归一化计算后进行量化,
26+ * 并将归一化计算结果,加法的计算结果,量化尺度和表示归一化后的标准差的倒数返回。
27+ * 计算公式:
28+ * x = x1 + x2
29+ * RmsNorm(x) = (x/RMS(x))*gamma) + beta
30+ * y, mxscale_out = dynamicMxQuant(RmsNorm(x), round_mode, scale_alg, dst_type)
31+ * rstd = 1/RMS(x)
32+ *
33+ * @param [in] x1:
34+ * 公式中的输入x1,数据类型支持FLOAT16、BFLOAT16,shape维度支持1-7维。
35+ * 支持非连续的Tensor,数据格式支持ND。
36+ * @param [in] x2:
37+ * 公式中的输入x2,数据类型支持FLOAT16、BFLOAT16,shape维度支持1-7维。
38+ * 支持非连续的Tensor,数据格式支持ND。
39+ * @param [in] gamma:
40+ * 公式中的输入gamma,数据类型默认与输入x1一致,若不一致,则显示设为FLOAT32,shape维度支持1维。
41+ * 支持非连续的Tensor,数据格式支持ND。
42+ * @param [in] beta:
43+ * 公式中的输入beta,数据类型和shape维度与gamma保持一致。
44+ * 支持非连续的Tensor,数据格式支持ND。
45+ * @param [in] epsilon: double 类型,层归一化中用到的防止除0的参数。
46+ * @param [in] scaleAlg:
47+ * 公式中的scale_alg,int 类型,表示mxscale_out的计算方法。
48+ * 支持取值0:OCP计算方法,和取值1:cuBLAS计算方法,当dst_type为FLOAT4_E2M1/FLOAT4_E1M2时仅支持取值为0
49+ * @param [in] roundMode:
50+ * 公式中的round_mode,string 类型,数据转换的模式。
51+ * 对应yOut数据类型为FLOAT4_E2M1/FLOAT4_E1M2时,支持{"rint", "floor", "round"},
52+ * 对应yOut数据类型为FLOAT8_E4M3FN/FLOAT8_E5M2时,仅支持{"rint"}。
53+ * @param [in] dstType:
54+ * 公式中的dst_type,int 类型,表示指定数据转换后yOut的类型。
55+ * 输入范围为{35, 36, 40, 41},分别对应{FLOAT8_E5M2, FLOAT8_E4M3FN, FLOAT4_E2M1, FLOAT4_E1M2}。
56+ * @param [in] outputRstd: bool 类型,表示指定是否输出有效的rstdOut,当为False时,rstdOut为无效输出。
57+ * @param [out] yOut:
58+ * 公式中的输出y,数据类型支持FLOAT4_E2M1、FLOAT4_E1M2、FLOAT8_E4M3FN、FLOAT8_E5M2,shape需要与x1一致。
59+ * 支持非连续的Tensor,数据格式支持ND。
60+ * @param [out] xOut:
61+ * 公式中的输出x,数据类型支持FLOAT16、BFLOAT16且需要与x1一致,shape需要与x1一致。
62+ * 支持非连续的Tensor,数据格式支持ND。
63+ * @param [out] mxscaleOut:
64+ * 公式中的输出mxscale_out,每个分组对应的量化尺度。数据类型支持FLOAT8_E8M0,shape维度支持2-8维。
65+ * 支持非连续的Tensor,数据格式支持ND。
66+ * @param [out] rstdOut:
67+ * 公式中的输出rstd,数据类型支持FLOAT,shape维度与输入x1保持一致。
68+ * 支持非连续的Tensor,数据格式支持ND。
69+ * @param [out] workspaceSize: 返回用户需要在npu device侧申请的workspace大小。
70+ * @param [out] executor: 返回op执行器,包含算子计算流程。
71+ * @return aclnnStatus: 返回状态码。
72+ */
73+ACLNN_API aclnnStatus aclnnAddRmsNormDynamicMxQuantGetWorkspaceSize(
74+ const aclTensor* x1, const aclTensor* x2, const aclTensor* gamma, const aclTensor* beta, double epsilon,
75+ int64_t scaleAlg, char* roundMode, int64_t dstType, bool outputRstd, aclTensor* yOut, aclTensor* xOut, aclTensor* mxscaleOut,
76+ aclTensor* rstdOut, uint64_t* workspaceSize, aclOpExecutor** executor);
77+ 
78+/**
79+ * @brief aclnnAddRmsNormDynamicMxQuant的第二段接口,用于执行计算。
80+ *
81+ * 算子功能:执行Add+RmsNorm+DynamicMxQuant计算。
82+ *
83+ * @param [in] workspace: 在npu device侧申请的workspace内存起址。
84+ * @param [in] workspaceSize: 在npu
85+ * device侧申请的workspace大小,由第一段接口aclnnAddRmsNormDynamicMxQuantGetWorkspaceSize获取。
86+ * @param [in] executor: op执行器,包含了算子计算流程。
87+ * @param [in] stream: acl stream流。
88+ * @return aclnnStatus: 返回状态码。
89+ */
90+ACLNN_API aclnnStatus
91+aclnnAddRmsNormDynamicMxQuant(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream);
92+ 
93+#ifdef __cplusplus
94+}
95+#endif
96+ 
97+#endif // OP_API_INC_LEVEL2_ADD_RMS_NORM_DYNAMIC_MX_QUANT_H_
Anorm/add_rms_norm_dynamic_mx_quant/op_host/op_api/add_rms_norm_dynamic_mx_quant.cpp+52-0
@@ -0,0 +1,52 @@
1+/**
2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+/*!
12+ * \file add_rms_norm_dynamic_mx_quant.cpp
13+ * \brief
14+ */
15+#include "add_rms_norm_dynamic_mx_quant.h"
16+#include "opdev/data_type_utils.h"
17+#include "opdev/format_utils.h"
18+#include "opdev/make_op_executor.h"
19+#include "opdev/op_def.h"
20+#include "opdev/op_dfx.h"
21+#include "opdev/op_executor.h"
22+#include "opdev/op_log.h"
23+#include "opdev/shape_utils.h"
24+#include "opdev/common_types.h"
25+#include "opdev/platform.h"
26+#include "aclnn_kernels/cast.h"
27+ 
28+using namespace op;
29+ 
30+namespace l0op {
31+OP_TYPE_REGISTER(AddRmsNormDynamicMxQuant); // 完成算子原型的关联
32+ 
33+const std::array<aclTensor*, ADD_RMS_NORM_DYNAMIC_MX_QUANT_OUT_NUM> AddRmsNormDynamicMxQuant(
34+ const aclTensor* x1, const aclTensor* x2, const aclTensor* gamma, const aclTensor* beta, double epsilon,
35+ int64_t scaleAlg, char* roundMode, int64_t dstType, bool outputRstd, aclTensor* yOut, aclTensor* xOut,
36+ aclTensor* mxscaleOut, aclTensor* rstdOut, aclOpExecutor* executor)
37+{
38+ // 调用接口,将算子执行任务加到执行器executor中
39+ L0_DFX(AddRmsNormDynamicMxQuant, x1, x2, gamma, beta, epsilon, scaleAlg, roundMode, dstType, outputRstd);
40+ 
41+ // 调用device的AddRmsNormDynamicMxQuant算子
42+ auto ret = ADD_TO_LAUNCHER_LIST_AICORE(
43+ AddRmsNormDynamicMxQuant, OP_INPUT(x1, x2, gamma, beta), OP_OUTPUT(yOut, xOut, mxscaleOut, rstdOut),
44+ OP_ATTR(static_cast<float>(epsilon), scaleAlg, roundMode, dstType, outputRstd));
45+ if (ret != ACL_SUCCESS) {
46+ OP_LOGE(ACLNN_ERR_INNER_NULLPTR, "AddRmsNormDynamicMxQuant ADD_TO_LAUNCHER_LIST_AICORE failed.");
47+ return {nullptr, nullptr, nullptr, nullptr};
48+ }
49+ return {yOut, xOut, mxscaleOut, rstdOut};
50+}
51+ 
52+} // namespace l0op
Anorm/add_rms_norm_dynamic_mx_quant/op_host/op_api/add_rms_norm_dynamic_mx_quant.h+30-0
@@ -0,0 +1,30 @@
1+/**
2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+/*!
12+ * \file add_rms_norm_dynamic_mx_quant.h
13+ * \brief
14+ */
15+ 
16+#ifndef OP_API_INC_LEVEL0_ADD_RMS_NORM_DYNAMIC_MX_QUANT_H_
17+#define OP_API_INC_LEVEL0_ADD_RMS_NORM_DYNAMIC_MX_QUANT_H_
18+ 
19+#include "opdev/op_executor.h"
20+ 
21+namespace l0op {
22+constexpr size_t ADD_RMS_NORM_DYNAMIC_MX_QUANT_OUT_NUM = 4;
23+ 
24+const std::array<aclTensor*, ADD_RMS_NORM_DYNAMIC_MX_QUANT_OUT_NUM> AddRmsNormDynamicMxQuant(
25+ const aclTensor* x1, const aclTensor* x2, const aclTensor* gamma, const aclTensor* beta, double epsilon,
26+ int64_t scaleAlg, char* roundMode, int64_t dstType, bool outputRstd, aclTensor* yOut, aclTensor* xOut,
27+ aclTensor* mxscaleOut, aclTensor* rstdOut, aclOpExecutor* executor);
28+} // namespace l0op
29+ 
30+#endif // OP_API_INC_LEVEL0_ADD_RMS_NORM_DYNAMIC_MX_QUANT_H_
Mnorm/rms_norm_dynamic_mx_quant/CMakeLists.txt+1-1
@@ -1,5 +1,5 @@
1# ----------------------------------------------------------------------------1# ----------------------------------------------------------------------------
2-# Copyright (c) 2025 Huawei Technologies Co., Ltd.2+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
3# This program is free software, you can redistribute it and/or modify it under the terms and conditions of3# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4# CANN Open Software License Agreement Version 2.0 (the "License").4# CANN Open Software License Agreement Version 2.0 (the "License").
5# Please refer to the License for details. You may not use this file except in compliance with the License.5# Please refer to the License for details. You may not use this file except in compliance with the License.
Mnorm/rms_norm_dynamic_mx_quant/README.md+12-12
@@ -22,7 +22,7 @@
22 y = \operatorname{RmsNorm}(x)=\frac{x}{\operatorname{Rms}(\mathbf{x})}\cdot gamma+beta, \quad \text { where } \operatorname{Rms}(\mathbf{x})=\sqrt{\frac{1}{n} \sum_{i=1}^n x_i^2+epsilon}22 y = \operatorname{RmsNorm}(x)=\frac{x}{\operatorname{Rms}(\mathbf{x})}\cdot gamma+beta, \quad \text { where } \operatorname{Rms}(\mathbf{x})=\sqrt{\frac{1}{n} \sum_{i=1}^n x_i^2+epsilon}
23 $$23 $$
24 24 
25-scaleAlg为0时:25+scale_alg为0时:
26 - 将RmsNorm输出y在尾轴维度上按k = 32个数分组,一组k个数 $\{\{V_i\}_{i=1}^{k}\}$ 动态量化为 $\{mxscale,\{P_i\}_{i=1}^{k}\}$26 - 将RmsNorm输出y在尾轴维度上按k = 32个数分组,一组k个数 $\{\{V_i\}_{i=1}^{k}\}$ 动态量化为 $\{mxscale,\{P_i\}_{i=1}^{k}\}$
27 $$27 $$
28 shared\_exp = floor(log_2(max_i(|V_i|))) - emax 28 shared\_exp = floor(log_2(max_i(|V_i|))) - emax
@@ -44,7 +44,7 @@
44 | FLOAT8_E4M3FN | 8 |44 | FLOAT8_E4M3FN | 8 |
45 | FLOAT8_E5M2 | 15 |45 | FLOAT8_E5M2 | 15 |
46 46 
47-scaleAlg为1时,只涉及FP8类型:47+scale_alg为1时,只涉及FP8类型:
48 - 将长向量按块分,每块长度为k,对每块单独计算一个块缩放因子$S_{fp32}^b$,再把块内所有元素用同一个$S_{fp32}^b$映射到目标低精度类型FP8。48 - 将长向量按块分,每块长度为k,对每块单独计算一个块缩放因子$S_{fp32}^b$,再把块内所有元素用同一个$S_{fp32}^b$映射到目标低精度类型FP8。
49 - 找到该块中数值的最大绝对值:49 - 找到该块中数值的最大绝对值:
50 $$50 $$
@@ -85,56 +85,56 @@
85 <tr>85 <tr>
86 <td>x</td>86 <td>x</td>
87 <td>输入</td>87 <td>输入</td>
88- <td>表示标准化过程中的源数据张量,对应公式中的`x`。</td>88+ <td>表示标准化过程中的源数据张量,对应公式中的x。</td>
89 <td>FLOAT16、BFLOAT16</td>89 <td>FLOAT16、BFLOAT16</td>
90 <td>ND</td>90 <td>ND</td>
91 </tr>91 </tr>
92 <tr>92 <tr>
93 <td>gamma</td>93 <td>gamma</td>
94 <td>输入</td>94 <td>输入</td>
95- <td>表示标准化过程中的权重张量,对应公式中的`gamma`。shape需要与x最后一维一致。</td>95+ <td>表示标准化过程中的权重张量,对应公式中的gamma。shape需要与x最后一维一致。</td>
96 <td>FLOAT16、BFLOAT16、FLOAT32</td>96 <td>FLOAT16、BFLOAT16、FLOAT32</td>
97 <td>ND</td>97 <td>ND</td>
98 </tr>98 </tr>
99 <tr>99 <tr>
100 <td>beta</td>100 <td>beta</td>
101 <td>可选输入</td>101 <td>可选输入</td>
102- <td>表示标准化过程中的偏置项,对应公式中的`beta`。shape必须与gamma一致。</td>102+ <td>表示标准化过程中的偏置项,对应公式中的beta。shape必须与gamma一致。</td>
103 <td>FLOAT16、BFLOAT16、FLOAT32</td>103 <td>FLOAT16、BFLOAT16、FLOAT32</td>
104 <td>ND</td>104 <td>ND</td>
105 </tr>105 </tr>
106 <tr>106 <tr>
107 <td>epsilon</td>107 <td>epsilon</td>
108 <td>可选属性</td>108 <td>可选属性</td>
109- <td><ul><li>表示添加到分母中的值,以确保数值稳定。对应公式中的`epsilon`。</li><li>默认值为1e-6。</li></ul></td>109+ <td><ul><li>表示添加到分母中的值,以确保数值稳定。对应公式中的epsilon。</li><li>默认值为1e-6。</li></ul></td>
110 <td>FLOAT32</td>110 <td>FLOAT32</td>
111 <td>-</td>111 <td>-</td>
112 </tr>112 </tr>
113 <tr>113 <tr>
114 <td>scale_alg</td>114 <td>scale_alg</td>
115 <td>可选属性</td>115 <td>可选属性</td>
116- <td><ul><li>表示mxscaleOut的计算方法,对应公式中的scaleAlg。</li><li>支持取值0和1,取值为0表示OCP实现,取值为1表示cuBLAS实现。当dstType为FLOAT4_E2M1/FLOAT4_E1M2时仅支持取值为0。</li><li>默认值为0。</li></ul></td>116+ <td><ul><li>表示mxscale的计算方法,对应公式中的scale_alg。</li><li>支持取值0和1,取值为0表示Open Compute Project(OCP)实现,取值为1表示cuBLAS实现。当dst_type为FLOAT4_E2M1/FLOAT4_E1M2时仅支持取值为0。</li><li>默认值为0。</li></ul></td>
117 <td>INT64</td>117 <td>INT64</td>
118 <td>-</td>118 <td>-</td>
119 </tr>119 </tr>
120 <tr>120 <tr>
121 <td>round_mode</td>121 <td>round_mode</td>
122 <td>可选属性</td>122 <td>可选属性</td>
123- <td><ul><li>表示数据转换的模式,对应公式中的round_mode。</li><li>当dstType为40/41时,支持{"rint", "floor", "round"}。</li><li>当dstType为36/35时,仅支持{"rint"}。</li><li>默认值为"rint"。</li></ul></td>123+ <td><ul><li>表示数据转换的模式,对应公式中的round_mode。</li><li>当dst_type为40/41时,支持{"rint", "floor", "round"}。</li><li>当dst_type为36/35时,仅支持{"rint"}。</li><li>默认值为"rint"。</li></ul></td>
124 <td>STRING</td>124 <td>STRING</td>
125 <td>-</td>125 <td>-</td>
126 </tr>126 </tr>
127 <tr>127 <tr>
128 <td>dst_type</td>128 <td>dst_type</td>
129 <td>可选属性</td>129 <td>可选属性</td>
130- <td><ul><li>表示指定数据转换后yOut的类型,对应公式中的DType。</li><li>输入范围为{35, 36, 40, 41},分别对应{FLOAT8_E5M2, FLOAT8_E4M3FN, FLOAT4_E2M1, FLOAT4_E1M2}。</li><li>默认值为40。</li></ul></td>130+ <td><ul><li>表示指定数据转换后y的类型,对应公式中的DType。</li><li>输入范围为{35, 36, 40, 41},分别对应{FLOAT8_E5M2, FLOAT8_E4M3FN, FLOAT4_E2M1, FLOAT4_E1M2}。</li><li>默认值为40。</li></ul></td>
131 <td>INT64</td>131 <td>INT64</td>
132 <td>-</td>132 <td>-</td>
133 </tr>133 </tr>
134 <tr>134 <tr>
135 <td>output_rstd</td>135 <td>output_rstd</td>
136 <td>可选属性</td>136 <td>可选属性</td>
137- <td><ul><li>表示指定是否输出有效的rstdOut。</li><li>支持True和False。</li><li>默认值为False。</li><li>当outputRstd为False时,算子不写出rstdOut返回shape[0]的空Tensor,此时rstdOut为无效占位输出。</li></ul></td>137+ <td><ul><li>表示指定是否输出有效的rstd。</li><li>支持True和False。</li><li>默认值为False。</li><li>当output_rstd为False时,算子不写出rstd,此时rstd为无效占位输出。</li></ul></td>
138 <td>BOOL</td>138 <td>BOOL</td>
139 <td>-</td>139 <td>-</td>
140 </tr>140 </tr>
@@ -155,7 +155,7 @@
155 <tr>155 <tr>
156 <td>rstd</td>156 <td>rstd</td>
157 <td>输出</td>157 <td>输出</td>
158- <td><ul><li>表示归一化后的标准差的倒数,对应公式中`Rms(x)`的倒数。</li><li>shape为与入参`x`的shape前几维保持一致,前几维指`x`的维度减去`gamma`的维度,表示不需要norm的维度。</li></ul></td>158+ <td><ul><li>表示归一化后的标准差的倒数,对应公式中Rms(x)的倒数。</li><li>shape为与入参x的shape前几维保持一致,前几维指x的维度减去gamma的维度,表示不需要norm的维度。</li></ul></td>
159 <td>FLOAT32</td>159 <td>FLOAT32</td>
160 <td>ND</td>160 <td>ND</td>
161 </tr>161 </tr>
@@ -171,7 +171,7 @@
171 - mxscale.shape[-1] = 2。171 - mxscale.shape[-1] = 2。
172 - 其他维度与输入x一致。172 - 其他维度与输入x一致。
173 173 
174-- 当输出yOut的数据类型为FLOAT4_E2M1或FLOAT4_E1M2,x尾轴的值必须为偶数。174+- 当输出y的数据类型为FLOAT4_E2M1或FLOAT4_E1M2,x尾轴的值必须为偶数。
175 175 
176- 输入gamma、可选输入beta的数据类型只能和x的数据类型保持一致或者为FLOAT32。176- 输入gamma、可选输入beta的数据类型只能和x的数据类型保持一致或者为FLOAT32。
177 177 
Mnorm/rms_norm_dynamic_mx_quant/docs/aclnnRmsNormDynamicMxQuant.md+28-27
@@ -74,7 +74,7 @@ aclnnStatus aclnnRmsNormDynamicMxQuantGetWorkspaceSize(
74 const aclTensor *beta,74 const aclTensor *beta,
75 double epsilon,75 double epsilon,
76 int64_t scaleAlg,76 int64_t scaleAlg,
77- char *roundModeOptional,77+ char *roundMode,
78 int64_t dstType,78 int64_t dstType,
79 bool outputRstd,79 bool outputRstd,
80 aclTensor *yOut,80 aclTensor *yOut,
@@ -121,8 +121,8 @@ aclnnStatus aclnnRmsNormDynamicMxQuant(
121 <tr>121 <tr>
122 <td>x(aclTensor*)</td>122 <td>x(aclTensor*)</td>
123 <td>输入</td>123 <td>输入</td>
124- <td>表示标准化过程中的源数据张量。对应公式中的`x`。</td>124+ <td>表示标准化过程中的源数据张量。对应公式中的x。</td>
125- <td><ul><li>不支持空Tensor。</li></ul></td>125+ <td><ul><li>不支持空Tensor。</li><li>具体约束详见约束说明。</li></ul></td>
126 <td>FLOAT16、BFLOAT16</td>126 <td>FLOAT16、BFLOAT16</td>
127 <td>ND</td>127 <td>ND</td>
128 <td>1-7</td>128 <td>1-7</td>
@@ -131,8 +131,8 @@ aclnnStatus aclnnRmsNormDynamicMxQuant(
131 <tr>131 <tr>
132 <td>gamma(aclTensor*)</td>132 <td>gamma(aclTensor*)</td>
133 <td>输入</td>133 <td>输入</td>
134- <td>表示标准化过程中的权重张量。对应公式中的`gamma`。</td>134+ <td>表示标准化过程中的权重张量。对应公式中的gamma。</td>
135- <td><ul><li>不支持空Tensor。</li><li>shape只能为一维,需要与`x`最后一维维度匹配。</li></ul></td>135+ <td><ul><li>不支持空Tensor。</li><li>shape只能为一维,需要与x最后一维维度匹配。</li><li>数据类型默认与输入x一致;若不一致,则显示设为FLOAT32。</li></ul></td>
136 <td>FLOAT16、BFLOAT16、FLOAT32</td>136 <td>FLOAT16、BFLOAT16、FLOAT32</td>
137 <td>ND</td>137 <td>ND</td>
138 <td>1</td>138 <td>1</td>
@@ -141,8 +141,8 @@ aclnnStatus aclnnRmsNormDynamicMxQuant(
141 <tr>141 <tr>
142 <td>beta(aclTensor*)</td>142 <td>beta(aclTensor*)</td>
143 <td>输入</td>143 <td>输入</td>
144- <td>表示标准化过程中的偏置项。对应公式中的`beta`。</td>144+ <td>表示标准化过程中的偏置项。对应公式中的beta。</td>
145- <td><ul><li>不支持空Tensor。</li><li>可选参数,支持传入空指针。</li><li>如果提供,shape和数据类型需要与`gamma`保持一致。</li></ul></td>145+ <td><ul><li>不支持空Tensor。</li><li>可选参数,支持传入空指针。</li><li>如果提供,shape和数据类型需要与gamma保持一致。</li></ul></td>
146 <td>FLOAT16、BFLOAT16、FLOAT32</td>146 <td>FLOAT16、BFLOAT16、FLOAT32</td>
147 <td>ND</td>147 <td>ND</td>
148 <td>1</td>148 <td>1</td>
@@ -151,7 +151,7 @@ aclnnStatus aclnnRmsNormDynamicMxQuant(
151 <tr>151 <tr>
152 <td>epsilon(double)</td>152 <td>epsilon(double)</td>
153 <td>输入</td>153 <td>输入</td>
154- <td>表示添加到分母中的值,以确保数值稳定。对应公式中的`epsilon`。</td>154+ <td>表示添加到分母中的值,以确保数值稳定。对应公式中的epsilon。</td>
155 <td><ul><li>建议传入较小正数,如1e-6。</li></ul></td>155 <td><ul><li>建议传入较小正数,如1e-6。</li></ul></td>
156 <td>-</td>156 <td>-</td>
157 <td>-</td>157 <td>-</td>
@@ -169,7 +169,7 @@ aclnnStatus aclnnRmsNormDynamicMxQuant(
169 <td>-</td>169 <td>-</td>
170 </tr>170 </tr>
171 <tr>171 <tr>
172- <td>roundModeOptional(char*)</td>172+ <td>roundMode(char*)</td>
173 <td>输入</td>173 <td>输入</td>
174 <td>表示数据转换的模式,对应公式中的round_mode。</td>174 <td>表示数据转换的模式,对应公式中的round_mode。</td>
175 <td><ul><li>当dstType为40/41时,支持{"rint", "floor", "round"}。</li><li>当dstType为36/35时,仅支持{"rint"}。</li></ul></td>175 <td><ul><li>当dstType为40/41时,支持{"rint", "floor", "round"}。</li><li>当dstType为36/35时,仅支持{"rint"}。</li></ul></td>
@@ -202,7 +202,7 @@ aclnnStatus aclnnRmsNormDynamicMxQuant(
202 <td>yOut(aclTensor*)</td>202 <td>yOut(aclTensor*)</td>
203 <td>输出</td>203 <td>输出</td>
204 <td>表示归一化并量化后的结果,对应公式中的Pi和di。</td>204 <td>表示归一化并量化后的结果,对应公式中的Pi和di。</td>
205- <td><ul><li>不支持空Tensor。</li><li>shape需要与输入`x`一致。</li></ul></td>205+ <td><ul><li>不支持空Tensor。</li><li>shape需要与输入x一致。</li><li>数据类型需要与dstType保持一致。</li></ul></td>
206 <td>FLOAT4_E2M1、FLOAT4_E1M2、FLOAT8_E4M3FN、FLOAT8_E5M2</td>206 <td>FLOAT4_E2M1、FLOAT4_E1M2、FLOAT8_E4M3FN、FLOAT8_E5M2</td>
207 <td>ND</td>207 <td>ND</td>
208 <td>1-7</td>208 <td>1-7</td>
@@ -212,7 +212,7 @@ aclnnStatus aclnnRmsNormDynamicMxQuant(
212 <td>mxscaleOut(aclTensor*)</td>212 <td>mxscaleOut(aclTensor*)</td>
213 <td>输出</td>213 <td>输出</td>
214 <td>表示每个分组对应的量化尺度,对应公式中的mxscale和Sb。</td>214 <td>表示每个分组对应的量化尺度,对应公式中的mxscale和Sb。</td>
215- <td><ul><li>不支持空Tensor。</li><li>shape的维度数为`x`的维度数加1。其中,前几维(`x`的维度减去`gamma`的维度数)与`x`对应维度保持一致,表示不需要norm的维度;后两维由MX量化决定:倒数第二维为ceil(`x`尾轴 / blocksize=32)再向上取偶数对齐(pad填充值为0),最后一维固定为2。具体计算过程见约束说明。</li></ul></td>215+ <td><ul><li>不支持空Tensor。</li><li>shape在尾轴上为x对应值除以blocksize=32向上取整,并对其进行偶pad,pad填充值0。</li><li>其余维度与x的shape前几保持一致,前几维x的维度减去gamma的维度,表示不需要norm的维度。</li><li>具体计算过程见约束说明。</li></ul></td>
216 <td>FLOAT8_E8M0</td>216 <td>FLOAT8_E8M0</td>
217 <td>ND</td>217 <td>ND</td>
218 <td>2-8</td>218 <td>2-8</td>
@@ -221,7 +221,7 @@ aclnnStatus aclnnRmsNormDynamicMxQuant(
221 <tr>221 <tr>
222 <td>rstdOut(aclTensor*)</td>222 <td>rstdOut(aclTensor*)</td>
223 <td>输出</td>223 <td>输出</td>
224- <td>表示归一化后的标准差的倒数。对应公式中`Rms(x)`的倒数。</td>224+ <td>表示归一化后的标准差的倒数。对应公式中Rms(x)的倒数。</td>
225 <td><ul><li>不支持空Tensor。</li><li>当outputRstd为True时,shape与入参`x`的shape前几维保持一致,前几维指`x`的维度减去`gamma`的维度,表示不需要norm的维度,rstdOut的-1轴是1。</li><li>当outputRstd为False时,该参数的最终输出无效。</li></ul></td>225 <td><ul><li>不支持空Tensor。</li><li>当outputRstd为True时,shape与入参`x`的shape前几维保持一致,前几维指`x`的维度减去`gamma`的维度,表示不需要norm的维度,rstdOut的-1轴是1。</li><li>当outputRstd为False时,该参数的最终输出无效。</li></ul></td>
226 <td>FLOAT32</td>226 <td>FLOAT32</td>
227 <td>ND</td>227 <td>ND</td>
@@ -271,37 +271,38 @@ aclnnStatus aclnnRmsNormDynamicMxQuant(
271 </thead>271 </thead>
272 <tbody>272 <tbody>
273 <tr>273 <tr>
274- <td>ACLNN_ERR_PARAM_NULLPTR</td>274+ <td rowspan="2">ACLNN_ERR_PARAM_NULLPTR</td>
275- <td>161001</td>275+ <td rowspan="2">161001</td>
276- <td>如果传入参数必选输入,输出或者必选属性,且是空指针,则返回161001。</td>276+ <td>传入的x、gamma、yOut和mxscaleOut是空指针。</td>
277 </tr>277 </tr>
278 <tr>278 <tr>
279- <td rowspan="2">ACLNN_ERR_PARAM_INVALID</td>279+ <td>当outputRstd为True时,传入rstdOut是空指针。</td>
280- <td rowspan="2">161002</td>
281- <td>输入或输出的数据类型不在支持的范围之内。</td>
282 </tr>280 </tr>
283 <tr>281 <tr>
284- <td>输入或输出的参数不满足参数说明的约束。</td>282+ <td rowspan="8">ACLNN_ERR_INNER_TILING_ERROR</td>
283+ <td rowspan="8">561002</td>
284+ <td>输入或输出参数的维度数和数据类型不在范围之内,dstType和yOut的数据类型不匹配。</td>
285 </tr>285 </tr>
286 <tr>286 <tr>
287- <td rowspan="6">ACLNN_ERR_INNER_TILING_ERROR</td>287+ <td>输入x和输出yOut的shape不是完全相同的shape。</td>
288- <td rowspan="6">561002</td>
289- <td>scaleAlg不是0或1,roundModeOptional(非空时)不是 {rint, floor, round}。</td>
290 </tr>288 </tr>
291 <tr>289 <tr>
292- <td>dstType fp8 时roundModeOptional是 rint。</td>290+ <td>gamma、beta(若存在)的shape不是完全相同的shape,或二者的维度数不1或轴长等于x的尾轴大小,或者类型不相同。</td>
293 </tr>291 </tr>
294 <tr>292 <tr>
295- <td>x、yOutshape是完全相同的shape。</td>293+ <td>gamma的维度和x的需要做norm的维度不相同,或rstdOut维度和x的不需要norm的维度不相同,或rstdOut对应x归一化维度的轴长不为1。</td>
296 </tr>294 </tr>
297 <tr>295 <tr>
298- <td>mxscaleOut的维度数等于输入维度数+1。</td>296+ <td>scaleAlg是0或1,roundMode不是 {rint, floor, round}。</td>
299 </tr>297 </tr>
300 <tr>298 <tr>
301- <td>gamma、beta(若存在)的shape不是完全相同的shape或者类型不是相同的类型。</td>299+ <td>dstType为 fp8 时roundMode不是 rint。</td>
302 </tr>300 </tr>
303 <tr>301 <tr>
304- <td>gamma的维度和x的需要作norm的维度相同,或rstdOut的维度和x的不需要norm的维度不相同,或rstdOut的需要norm的维度不为1。</td>302+ <td>dstType为 fp4 时,scaleAlg是0,或者输入x的尾轴能被2整除。</td>
303+ </tr>
304+ <tr>
305+ <td>mxscaleOut的维度数不等于输入x的维度数+1,或轴长不符合约束说明。</td>
305 </tr>306 </tr>
306 </tbody></table>307 </tbody></table>
307 308 
Mnorm/rms_norm_dynamic_mx_quant/examples/test_aclnn_rms_norm_dynamic_mx_quant.cpp+1-1文件内容审核中,请稍后刷新重试
Mnorm/rms_norm_dynamic_mx_quant/op_graph/CMakeLists.txt+1-1
@@ -1,5 +1,5 @@
1#1#
2-# Copyright (c) 2025 Huawei Technologies Co., Ltd.2+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
3# This program is free software, you can redistribute it and/or modify it under the terms and conditions of 3# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4# CANN Open Software License Agreement Version 2.0 (the "License").4# CANN Open Software License Agreement Version 2.0 (the "License").
5# Please refer to the License for details. You may not use this file except in compliance with the License.5# Please refer to the License for details. You may not use this file except in compliance with the License.
Mnorm/rms_norm_dynamic_mx_quant/op_graph/rms_norm_dynamic_mx_quant_proto.h+1-1
@@ -1,5 +1,5 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.5 * Please refer to the License for details. You may not use this file except in compliance with the License.
Mnorm/rms_norm_dynamic_mx_quant/op_host/CMakeLists.txt+2-2
@@ -1,5 +1,5 @@
1# ----------------------------------------------------------------------------1# ----------------------------------------------------------------------------
2-# Copyright (c) 2025 Huawei Technologies Co., Ltd.2+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
3# This program is free software, you can redistribute it and/or modify it under the terms and conditions of3# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4# CANN Open Software License Agreement Version 2.0 (the "License").4# CANN Open Software License Agreement Version 2.0 (the "License").
5# Please refer to the License for details. You may not use this file except in compliance with the License.5# Please refer to the License for details. You may not use this file except in compliance with the License.
@@ -8,4 +8,4 @@
8# See LICENSE in the root of the software repository for the full text of the License.8# See LICENSE in the root of the software repository for the full text of the License.
9# ----------------------------------------------------------------------------9# ----------------------------------------------------------------------------
10 10 
11-add_modules_sources(HOSTNAME ${OPHOST_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR} OPTYPE rms_norm_dynamic_mx_quant ACLNNTYPE aclnn COMPUTE_UNIT "ascend950" TILING_DIR "arch35" DISABLE_IN_OPP TRUE)11+add_modules_sources(HOSTNAME ${OPHOST_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR} OPTYPE rms_norm_dynamic_mx_quant ACLNNTYPE aclnn_exclude COMPUTE_UNIT "ascend950" TILING_DIR "arch35" DISABLE_IN_OPP TRUE)
Mnorm/rms_norm_dynamic_mx_quant/op_host/arch35/rms_norm_dynamic_mx_quant_base_tiling.cpp+1-1
@@ -1,5 +1,5 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.5 * Please refer to the License for details. You may not use this file except in compliance with the License.
Mnorm/rms_norm_dynamic_mx_quant/op_host/arch35/rms_norm_dynamic_mx_quant_full_load_tiling.cpp+1-1
@@ -1,5 +1,5 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.5 * Please refer to the License for details. You may not use this file except in compliance with the License.
Mnorm/rms_norm_dynamic_mx_quant/op_host/arch35/rms_norm_dynamic_mx_quant_tiling_arch35.h+1-1
@@ -1,5 +1,5 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.5 * Please refer to the License for details. You may not use this file except in compliance with the License.
Anorm/rms_norm_dynamic_mx_quant/op_host/op_api/aclnn_rms_norm_dynamic_mx_quant.cpp+146-0
@@ -0,0 +1,146 @@
1+/**
2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+#include "aclnn/aclnn_base.h"
11+#include "op_api/op_api_def.h"
12+ 
13+#include "opdev/common_types.h"
14+#include "opdev/data_type_utils.h"
15+#include "opdev/op_executor.h"
16+#include "opdev/op_log.h"
17+#include "opdev/format_utils.h"
18+#include "opdev/tensor_view_utils.h"
19+#include "opdev/op_dfx.h"
20+#include "opdev/shape_utils.h"
21+#include "opdev/platform.h"
22+ 
23+#include "aclnn_kernels/common/op_error_check.h"
24+#include "aclnn_kernels/cast.h"
25+#include "aclnn_kernels/contiguous.h"
26+#include "op_api/aclnn_util.h"
27+ 
28+#include "rms_norm_dynamic_mx_quant.h"
29+#include "aclnn_rms_norm_dynamic_mx_quant.h"
30+ 
31+using namespace op;
32+#ifdef __cplusplus
33+extern "C" {
34+#endif
35+ 
36+constexpr int IDX_0 = 0;
37+constexpr int IDX_1 = 1;
38+constexpr int IDX_2 = 2;
39+ 
40+static bool CheckNotNull(
41+ const aclTensor* x, const aclTensor* gamma, aclTensor* yOut,
42+ aclTensor* mxscaleOut, bool outputRstd, aclTensor* rstdOut)
43+{
44+ OP_CHECK_NULL(x, return false);
45+ OP_CHECK_NULL(gamma, return false);
46+ // beta 是可选输入,不校验nullptr
47+ OP_CHECK_NULL(yOut, return false);
48+ OP_CHECK_NULL(mxscaleOut, return false);
49+ // rstdOut 根据 outputRstd 决定是否校验
50+ if (outputRstd) {
51+ OP_CHECK_NULL(rstdOut, return false);
52+ }
53+ return true;
54+}
55+ 
56+static aclnnStatus ComputeRmsNormDynamicMxQuant(
57+ const aclTensor* x, const aclTensor* gamma, const aclTensor* beta, double epsilon,
58+ int64_t scaleAlg, char* roundMode, int64_t dstType, bool outputRstd, aclTensor* yOut,
59+ aclTensor* mxscaleOut, aclTensor* rstdOut, aclOpExecutor* executor)
60+{
61+ // 创建输出Tensor
62+ aclTensor* y_output = executor->AllocTensor(yOut->GetViewShape(), yOut->GetDataType(), yOut->GetViewFormat());
63+ aclTensor* mxscale_output =
64+ executor->AllocTensor(mxscaleOut->GetViewShape(), mxscaleOut->GetDataType(), mxscaleOut->GetViewFormat());
65+ aclTensor* rstd_output =
66+ (outputRstd) ?
67+ executor->AllocTensor(rstdOut->GetViewShape(), rstdOut->GetDataType(), rstdOut->GetViewFormat()) :
68+ executor->AllocTensor(op::Shape({0}), op::DataType::DT_FLOAT, op::Format::FORMAT_ND);
W
Wwangyu_ai4月8日

此条代码评论区间+65+68

同上

likedislike
刘琦
刘琦
4月9日 评论:
69+ 
70+ auto RmsNormDynamicMxQuantOuts = l0op::RmsNormDynamicMxQuant(
71+ x, gamma, beta, epsilon, scaleAlg, roundMode, dstType, outputRstd, y_output, mxscale_output,
72+ rstd_output, executor);
73+ 
74+ auto yComputeOut = std::get<IDX_0>(RmsNormDynamicMxQuantOuts);
75+ auto mxscaleComputeOut = std::get<IDX_1>(RmsNormDynamicMxQuantOuts);
76+ auto rstdComputeOut = std::get<IDX_2>(RmsNormDynamicMxQuantOuts);
77+ 
78+ // 校验输出不为空
79+ CHECK_RET(yComputeOut != nullptr, ACLNN_ERR_INNER_NULLPTR);
80+ CHECK_RET(mxscaleComputeOut != nullptr, ACLNN_ERR_INNER_NULLPTR);
81+ 
82+ // 将结果拷贝到输出tensor
83+ auto viewCopyYResult = l0op::ViewCopy(yComputeOut, yOut, executor);
84+ CHECK_RET(viewCopyYResult != nullptr, ACLNN_ERR_INNER_NULLPTR);
85+ 
86+ auto viewCopyMxscaleResult = l0op::ViewCopy(mxscaleComputeOut, mxscaleOut, executor);
87+ CHECK_RET(viewCopyMxscaleResult != nullptr, ACLNN_ERR_INNER_NULLPTR);
88+ 
89+ if (outputRstd) {
90+ CHECK_RET(rstdComputeOut != nullptr, ACLNN_ERR_INNER_NULLPTR);
91+ auto viewCopyRstdResult = l0op::ViewCopy(rstdComputeOut, rstdOut, executor);
92+ CHECK_RET(viewCopyRstdResult != nullptr, ACLNN_ERR_INNER_NULLPTR);
93+ }
94+ 
95+ return ACLNN_SUCCESS;
96+}
97+ 
98+aclnnStatus aclnnRmsNormDynamicMxQuantGetWorkspaceSize(
99+ const aclTensor* x, const aclTensor* gamma, const aclTensor* beta, double epsilon,
100+ int64_t scaleAlg, char* roundMode, int64_t dstType, bool outputRstd, aclTensor* yOut,
101+ aclTensor* mxscaleOut, aclTensor* rstdOut, uint64_t* workspaceSize, aclOpExecutor** executor)
102+{
103+ OP_LOGD("Enter aclnnRmsNormDynamicMxQuantGetWorkspaceSize.");
104+ L2_DFX_PHASE_1(
105+ aclnnRmsNormDynamicMxQuant, DFX_IN(x, gamma, beta, epsilon, scaleAlg, roundMode, dstType, outputRstd),
106+ DFX_OUT(yOut, mxscaleOut, rstdOut));
107+ 
108+ // 创建OpExecutor
109+ auto uniqueExecutor = CREATE_EXECUTOR();
110+ CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR);
111+ 
112+ // 检查必选输入/输出是否为空指针
113+ CHECK_RET(CheckNotNull(x, gamma, yOut, mxscaleOut, outputRstd, rstdOut), ACLNN_ERR_PARAM_NULLPTR);
114+ 
115+ // 固定写法,将输入转换成连续的tensor,可选输入不做判空校验
116+ auto xCont = l0op::Contiguous(x, uniqueExecutor.get());
117+ auto gammaCont = l0op::Contiguous(gamma, uniqueExecutor.get());
118+ 
119+ CHECK_RET(xCont != nullptr, ACLNN_ERR_INNER_NULLPTR);
120+ CHECK_RET(gammaCont != nullptr, ACLNN_ERR_INNER_NULLPTR);
121+ 
122+ const aclTensor* betaCont = (beta == nullptr) ? nullptr : l0op::Contiguous(beta, uniqueExecutor.get());
123+ 
124+ auto ret = ComputeRmsNormDynamicMxQuant(
125+ xCont, gammaCont, betaCont, epsilon, scaleAlg, roundMode, dstType, outputRstd, yOut, mxscaleOut,
126+ rstdOut, uniqueExecutor.get());
127+ CHECK_RET(ret == ACLNN_SUCCESS, ret);
128+ 
129+ // 获取计算过程中需要使用的workspace大小
130+ *workspaceSize = uniqueExecutor->GetWorkspaceSize();
131+ uniqueExecutor.ReleaseTo(executor);
132+ OP_LOGD("Finish aclnnRmsNormDynamicMxQuantGetWorkspaceSize.");
133+ return ACLNN_SUCCESS;
134+}
135+ 
136+aclnnStatus aclnnRmsNormDynamicMxQuant(
137+ void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream)
138+{
139+ L2_DFX_PHASE_2(aclnnRmsNormDynamicMxQuant);
140+ // 固定写法,调用框架能力,完成计算
141+ return CommonOpExecutorRun(workspace, workspaceSize, executor, stream);
142+}
143+ 
144+#ifdef __cplusplus
145+}
146+#endif
Anorm/rms_norm_dynamic_mx_quant/op_host/op_api/aclnn_rms_norm_dynamic_mx_quant.h+90-0
@@ -0,0 +1,90 @@
1+/**
2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+#ifndef OP_API_INC_LEVEL2_RMS_NORM_DYNAMIC_MX_QUANT_H_
12+#define OP_API_INC_LEVEL2_RMS_NORM_DYNAMIC_MX_QUANT_H_
13+ 
14+#include "aclnn/aclnn_base.h"
15+#include "aclnn_util.h"
16+ 
17+#ifdef __cplusplus
18+extern "C" {
19+#endif
20+ 
21+/**
22+ * @brief aclnnRmsNormDynamicMxQuant的第一段接口,根据具体的计算流程,计算workspace大小。
23+ * @domain aclnn_ops_infer
24+ *
25+ * 算子功能:RmsNorm + 量化计算的融合算子,将加法的计算结果做层归一化计算后进行量化,
26+ * 并将归一化计算结果,加法的计算结果,量化尺度和表示归一化后的标准差的倒数返回。
27+ * 计算公式:
28+ * RmsNorm(x) = (x/RMS(x))*gamma) + beta
29+ * y, mxscale_out = dynamicMxQuant(RmsNorm(x), round_mode, scale_alg, dst_type)
30+ * rstd = 1/RMS(x)
31+ *
32+ * @param [in] x:
33+ * 公式中的输入x1,数据类型支持FLOAT16、BFLOAT16,shape维度支持1-7维。
34+ * 支持非连续的Tensor,数据格式支持ND。
35+ * @param [in] gamma:
36+ * 公式中的输入gamma,数据类型默认与输入x1一致,若不一致,则显示设为FLOAT32,shape维度支持1维。
37+ * 支持非连续的Tensor,数据格式支持ND。
38+ * @param [in] beta:
39+ * 公式中的输入beta,数据类型和shape维度与gamma保持一致。
40+ * 支持非连续的Tensor,数据格式支持ND。
41+ * @param [in] epsilon: double 类型,层归一化中用到的防止除0的参数。
42+ * @param [in] scaleAlg:
43+ * 公式中的scale_alg,int 类型,表示mxscale_out的计算方法。
44+ * 支持取值0:OCP计算方法,和取值1:cuBLAS计算方法,当dst_type为FLOAT4_E2M1/FLOAT4_E1M2时仅支持取值为0
45+ * @param [in] roundMode:
46+ * 公式中的round_mode,string 类型,数据转换的模式。
47+ * 对应yOut数据类型为FLOAT4_E2M1/FLOAT4_E1M2时,支持{"rint", "floor", "round"},
48+ * 对应yOut数据类型为FLOAT8_E4M3FN/FLOAT8_E5M2时,仅支持{"rint"}。
49+ * @param [in] dstType:
50+ * 公式中的dst_type,int 类型,表示指定数据转换后yOut的类型。
51+ * 输入范围为{35, 36, 40, 41},分别对应{FLOAT8_E5M2, FLOAT8_E4M3FN, FLOAT4_E2M1, FLOAT4_E1M2}。
52+ * @param [in] outputRstd: bool 类型,表示指定是否输出有效的rstdOut,当为False时,rstdOut为无效输出。
53+ * @param [out] yOut:
54+ * 公式中的输出y,数据类型支持FLOAT4_E2M1、FLOAT4_E1M2、FLOAT8_E4M3FN、FLOAT8_E5M2,shape需要与x一致。
55+ * 支持非连续的Tensor,数据格式支持ND。
56+ * @param [out] mxscaleOut:
57+ * 公式中的输出mxscale_out,每个分组对应的量化尺度。数据类型支持FLOAT8_E8M0,shape维度支持2-8维。
58+ * 支持非连续的Tensor,数据格式支持ND。
59+ * @param [out] rstdOut:
60+ * 公式中的输出rstd,数据类型支持FLOAT,shape维度与输入x保持一致。
61+ * 支持空Tensor,数据格式支持ND。
62+ * @param [out] workspaceSize: 返回用户需要在npu device侧申请的workspace大小。
63+ * @param [out] executor: 返回op执行器,包含算子计算流程。
64+ * @return aclnnStatus: 返回状态码。
65+ */
66+ACLNN_API aclnnStatus aclnnRmsNormDynamicMxQuantGetWorkspaceSize(
67+ const aclTensor* x, const aclTensor* gamma, const aclTensor* beta, double epsilon,
68+ int64_t scaleAlg, char* roundMode, int64_t dstType, bool outputRstd, aclTensor* yOut,
69+ aclTensor* mxscaleOut, aclTensor* rstdOut, uint64_t* workspaceSize, aclOpExecutor** executor);
70+ 
71+/**
72+ * @brief aclnnRmsNormDynamicMxQuant的第二段接口,用于执行计算。
73+ *
74+ * 算子功能:执行RmsNorm+DynamicMxQuant计算。
75+ *
76+ * @param [in] workspace: 在npu device侧申请的workspace内存起址。
77+ * @param [in] workspaceSize: 在npu
78+ * device侧申请的workspace大小,由第一段接口aclnnRmsNormDynamicMxQuantGetWorkspaceSize获取。
79+ * @param [in] executor: op执行器,包含了算子计算流程。
80+ * @param [in] stream: acl stream流。
81+ * @return aclnnStatus: 返回状态码。
82+ */
83+ACLNN_API aclnnStatus
84+aclnnRmsNormDynamicMxQuant(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream);
85+ 
86+#ifdef __cplusplus
87+}
88+#endif
89+ 
90+#endif // OP_API_INC_LEVEL2_RMS_NORM_DYNAMIC_MX_QUANT_H_
Anorm/rms_norm_dynamic_mx_quant/op_host/op_api/rms_norm_dynamic_mx_quant.cpp+52-0
@@ -0,0 +1,52 @@
1+/**
2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+/*!
12+ * \file rms_norm_dynamic_mx_quant.cpp
13+ * \brief
14+ */
15+#include "rms_norm_dynamic_mx_quant.h"
16+#include "opdev/data_type_utils.h"
17+#include "opdev/format_utils.h"
18+#include "opdev/make_op_executor.h"
19+#include "opdev/op_def.h"
20+#include "opdev/op_dfx.h"
21+#include "opdev/op_executor.h"
22+#include "opdev/op_log.h"
23+#include "opdev/shape_utils.h"
24+#include "opdev/common_types.h"
25+#include "opdev/platform.h"
26+#include "aclnn_kernels/cast.h"
27+ 
28+using namespace op;
29+ 
30+namespace l0op {
31+OP_TYPE_REGISTER(RmsNormDynamicMxQuant); // 完成算子原型的关联
32+ 
33+const std::array<aclTensor*, RMS_NORM_DYNAMIC_MX_QUANT_OUT_NUM> RmsNormDynamicMxQuant(
34+ const aclTensor* x, const aclTensor* gamma, const aclTensor* beta, double epsilon,
35+ int64_t scaleAlg, char* roundMode, int64_t dstType, bool outputRstd, aclTensor* yOut,
36+ aclTensor* mxscaleOut, aclTensor* rstdOut, aclOpExecutor* executor)
37+{
38+ // 调用接口,将算子执行任务加到执行器executor中
39+ L0_DFX(RmsNormDynamicMxQuant, x, gamma, beta, epsilon, scaleAlg, roundMode, dstType, outputRstd);
40+ 
41+ // 调用device的RmsNormDynamicMxQuant算子
42+ auto ret = ADD_TO_LAUNCHER_LIST_AICORE(
43+ RmsNormDynamicMxQuant, OP_INPUT(x, gamma, beta), OP_OUTPUT(yOut, mxscaleOut, rstdOut),
44+ OP_ATTR(static_cast<float>(epsilon), scaleAlg, roundMode, dstType, outputRstd));
45+ if (ret != ACL_SUCCESS) {
46+ OP_LOGE(ACLNN_ERR_INNER_NULLPTR, "RmsNormDynamicMxQuant ADD_TO_LAUNCHER_LIST_AICORE failed.");
47+ return {nullptr, nullptr, nullptr};
48+ }
49+ return {yOut, mxscaleOut, rstdOut};
50+}
51+ 
52+} // namespace l0op
Anorm/rms_norm_dynamic_mx_quant/op_host/op_api/rms_norm_dynamic_mx_quant.h+30-0
@@ -0,0 +1,30 @@
1+/**
2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+/*!
12+ * \file rms_norm_dynamic_mx_quant.h
13+ * \brief
14+ */
15+
16+#ifndef OP_API_INC_LEVEL0_RMS_NORM_DYNAMIC_MX_QUANT_H_
17+#define OP_API_INC_LEVEL0_RMS_NORM_DYNAMIC_MX_QUANT_H_
18+ 
19+#include "opdev/op_executor.h"
20+ 
21+namespace l0op {
22+constexpr size_t RMS_NORM_DYNAMIC_MX_QUANT_OUT_NUM = 3;
23+ 
24+const std::array<aclTensor*, RMS_NORM_DYNAMIC_MX_QUANT_OUT_NUM> RmsNormDynamicMxQuant(
25+ const aclTensor* x, const aclTensor* gamma, const aclTensor* beta, double epsilon,
26+ int64_t scaleAlg, char* roundMode, int64_t dstType, bool outputRstd, aclTensor* yOut,
27+ aclTensor* mxscaleOut, aclTensor* rstdOut, aclOpExecutor* executor);
28+} // namespace l0op
29+ 
30+#endif // OP_API_INC_LEVEL0_RMS_NORM_DYNAMIC_MX_QUANT_H_
Mnorm/rms_norm_dynamic_mx_quant/op_host/rms_norm_dynamic_mx_quant_def.cpp+1-1
@@ -1,5 +1,5 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.5 * Please refer to the License for details. You may not use this file except in compliance with the License.
Mnorm/rms_norm_dynamic_mx_quant/op_host/rms_norm_dynamic_mx_quant_infershape.cpp+1-1
@@ -1,5 +1,5 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.5 * Please refer to the License for details. You may not use this file except in compliance with the License.
Mnorm/rms_norm_dynamic_mx_quant/op_kernel/arch35/rms_norm_dynamic_mx_quant_common.h+1-1
@@ -1,5 +1,5 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.5 * Please refer to the License for details. You may not use this file except in compliance with the License.
Mnorm/rms_norm_dynamic_mx_quant/op_kernel/arch35/rms_norm_dynamic_mx_quant_full_load.h+1-1
@@ -1,5 +1,5 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.5 * Please refer to the License for details. You may not use this file except in compliance with the License.
Mnorm/rms_norm_dynamic_mx_quant/op_kernel/rms_norm_dynamic_mx_quant_apt.cpp+1-1
@@ -1,5 +1,5 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.5 * Please refer to the License for details. You may not use this file except in compliance with the License.
Mnorm/rms_norm_dynamic_mx_quant/tests/CMakeLists.txt+1-1
@@ -1,5 +1,5 @@
1# ----------------------------------------------------------------------------1# ----------------------------------------------------------------------------
2-# Copyright (c) 2025 Huawei Technologies Co., Ltd.2+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
3# This program is free software, you can redistribute it and/or modify it under the terms and conditions of3# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4# CANN Open Software License Agreement Version 2.0 (the "License").4# CANN Open Software License Agreement Version 2.0 (the "License").
5# Please refer to the License for details. You may not use this file except in compliance with the License.5# Please refer to the License for details. You may not use this file except in compliance with the License.
Mnorm/rms_norm_dynamic_mx_quant/tests/ut/op_host/arch35/test_rms_norm_dynamic_mx_quant_tiling_arch35.cpp+1-1
@@ -1,5 +1,5 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.5 * Please refer to the License for details. You may not use this file except in compliance with the License.
Mnorm/rms_norm_dynamic_mx_quant/tests/ut/op_host/test_rms_norm_dynamic_mx_quant_infershape.cpp+1-1
@@ -1,5 +1,5 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.5 * Please refer to the License for details. You may not use this file except in compliance with the License.