已合并
add AscendAntiQuantV2 #1643
clwsy创建于 2月6日
add AscendAntiQuantV2 #1643
已合并
共 37 个文件变更+8959-110
| @@ -2927,12 +2927,12 @@ | |||
| 2927 | <tr> | 2927 | <tr> |
| 2928 | <td>quant</td> | 2928 | <td>quant</td> |
| 2929 | <td><a href="../../quant/ascend_anti_quant_v2/README.md">ascend_anti_quant_v2</a></td> | 2929 | <td><a href="../../quant/ascend_anti_quant_v2/README.md">ascend_anti_quant_v2</a></td> |
| 2930 | - <td>✗</td> | ||
| 2931 | <td>✓</td> | 2930 | <td>✓</td> |
| 2932 | <td>✓</td> | 2931 | <td>✓</td> |
| 2933 | - <td>✗</td> | 2932 | + <td>✓</td> |
| 2933 | + <td>✓</td> | ||
| 2934 | <td>AI Core</td> | 2934 | <td>AI Core</td> |
| 2935 | - <td>该算子暂无Ascend C代码实现,欢迎开发者补充贡献,贡献方式参考<a href="../../CONTRIBUTING.md">贡献指南</a>。</td> | 2935 | + <td>根据输入的scale和offset对输入x进行反量化。</td> |
| 2936 | </tr> | 2936 | </tr> |
| 2937 | <tr> | 2937 | <tr> |
| 2938 | <td>quant</td> | 2938 | <td>quant</td> |
| @@ -1,3 +1,126 @@ | |||
| 1 | # AscendAntiQuantV2 | 1 | # AscendAntiQuantV2 |
| 2 | 2 | ||
| 3 | -本目录仅包含AscendAntiQuantV2算子对应的aclnn接口;如您想要贡献该算子的AscendC实现,请参考[贡献流程](../../CONTRIBUTING.md)。 | 3 | +## 产品支持情况 |
| 4 | + | ||
| 5 | +| 产品 | 是否支持 | | ||
| 6 | +| :----------------------------------------------------------- | :------: | | ||
| 7 | +| <term>Ascend 950PR/Ascend 950DT</term> | √ | | ||
| 8 | +| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ | | ||
| 9 | +| <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品 </term> | √ | | ||
| 10 | +| <term>Atlas 200I/500 A2 推理产品</term> | × | | ||
| 11 | +| <term>Atlas 推理系列产品 </term> | √ | | ||
| 12 | +| <term>Atlas 训练系列产品</term> | × | | ||
| 13 | + | ||
| 14 | +## 功能说明 | ||
| 15 | + | ||
| 16 | +- 算子功能:根据输入的scale和offset对输入x进行反量化。 | ||
| 17 | + | ||
| 18 | +- 计算公式: | ||
| 19 | + - sqrtMode为true,offset为None时,计算公式为: | ||
| 20 | + | ||
| 21 | + $$ | ||
| 22 | + y = cast\_to\_dst\_type((x) * scale * scale) | ||
| 23 | + $$ | ||
| 24 | + | ||
| 25 | + - sqrtMode为true,offset不为None时,计算公式为: | ||
| 26 | + | ||
| 27 | + $$ | ||
| 28 | + y = cast\_to\_dst\_type((x + offset) * scale * scale) | ||
| 29 | + $$ | ||
| 30 | + | ||
| 31 | + - sqrtMode为false,offset为None时,计算公式为: | ||
| 32 | + | ||
| 33 | + $$ | ||
| 34 | + y = cast\_to\_dst\_type((x) * scale) | ||
| 35 | + $$ | ||
| 36 | + | ||
| 37 | + - sqrtMode为false,offset不为None时,计算公式为: | ||
| 38 | + | ||
| 39 | + $$ | ||
| 40 | + y = cast\_to\_dst\_type((x + offset) * scale) | ||
| 41 | + $$ | ||
| 42 | + | ||
| 43 | +## 参数说明 | ||
| 44 | + | ||
C | |||
| 45 | +<table style="undefined;table-layout: fixed; width: 1005px"><colgroup> | ||
| 46 | + <col style="width: 170px"> | ||
| 47 | + <col style="width: 170px"> | ||
| 48 | + <col style="width: 352px"> | ||
| 49 | + <col style="width: 213px"> | ||
| 50 | + <col style="width: 100px"> | ||
| 51 | + </colgroup> | ||
| 52 | + <thead> | ||
| 53 | + <tr> | ||
| 54 | + <th>参数名</th> | ||
| 55 | + <th>输入/输出/属性</th> | ||
| 56 | + <th>描述</th> | ||
| 57 | + <th>数据类型</th> | ||
| 58 | + <th>数据格式</th> | ||
| 59 | + </tr></thead> | ||
| 60 | + <tbody> | ||
| 61 | + <tr> | ||
| 62 | + <td>x</td> | ||
| 63 | + <td>输入</td> | ||
| 64 | + <td><ul><li>表示算子输入的Tensor,对应公式中的x;</li><li>不支持空Tensor;</li><li>当数据类型是INT4时,shape的尾轴为偶数。</td> | ||
| 65 | + <td>INT4、INT8、HIFLOAT8、FLOAT8_E4M3、FLOAT8_E5M2</td> | ||
| 66 | + <td>ND</td> | ||
| 67 | + </tr> | ||
| 68 | + <tr> | ||
| 69 | + <td>scale</td> | ||
| 70 | + <td>输入</td> | ||
| 71 | + <td><ul><li>表示反量化中的scale值。对应公式中的scale;</li><li>不支持空Tensor;</li><li>scale的维数必须与x相同,或者是1维;</li><li>如果x是1维,scale的形状必须是[1]或与x相同;</li><li>如果scale是1维,其大小必须是1、x[-1]或x[-2];</li><li>如果scale是多维,最多只能有一个非1的维度,且这个非1的维度只能是-1或-2轴;</li><li>当输入x的类型为HIFLOAT8、FLOAT8_E4M3、FLOAT8_E5M2时,scale只支持FLOAT32。</td> | ||
| 72 | + <td>FLOAT32、BFLOAT16</td> | ||
| 73 | + <td>ND</td> | ||
| 74 | + </tr> | ||
| 75 | + <tr> | ||
| 76 | + <td>offset</td> | ||
| 77 | + <td>可选输入</td> | ||
| 78 | + <td><ul><li>表示反量化中的offset值。对应公式中的offset;</li><li>不支持空Tensor;</li><li>数据类型和shape需要与scale保持一致。</td> | ||
| 79 | + <td>和scale一致</td> | ||
| 80 | + <td>ND</td> | ||
| 81 | + </tr> | ||
| 82 | + <tr> | ||
| 83 | + <td>dst_type</td> | ||
| 84 | + <td>可选属性</td> | ||
| 85 | + <td><ul><li>表示输出的数据类型;</li><li>支持取值1、27,分别表示FLOAT16、BFLOAT16。</td> | ||
| 86 | + <td>INT64</td> | ||
| 87 | + <td>-</td> | ||
| 88 | + </tr> | ||
| 89 | + <tr> | ||
| 90 | + <td>sqrt_mode</td> | ||
| 91 | + <td>可选属性</td> | ||
| 92 | + <td><ul><li>表示scale参与计算的逻辑。对应公式中的sqrtMode;</li><li>当x的数据类型为HIFLOAT8、FLOAT8_E4M3、FLOAT8_E5M2时,sqrtMode为false。</td> | ||
| 93 | + <td>BOOL</td> | ||
| 94 | + <td>-</td> | ||
| 95 | + </tr> | ||
| 96 | + <tr> | ||
| 97 | + <td>y</td> | ||
| 98 | + <td>输出</td> | ||
| 99 | + <td><ul><li>表示反量化的计算输出。对应公式中的y;</li><li>shape和输入x一致。</td> | ||
| 100 | + <td>FLOAT16、BFLOAT16</td> | ||
| 101 | + <td>ND</td> | ||
| 102 | + </tr> | ||
| 103 | + </tbody> | ||
| 104 | +</table> | ||
| 105 | + | ||
| 106 | +- <term>Atlas 推理系列产品</term>: | ||
| 107 | + - 数据类型: | ||
| 108 | + - 入参`x`仅支持INT8。 | ||
| 109 | + - 入参`scale`、`offset`和出参`y`不支持BFLOAT16。 | ||
| 110 | + - 入参`dstType`仅支持取值1,表示FLOAT16。 | ||
| 111 | + - 入参`scale`、`offset`仅支持一维,且只能等于x尾轴大小或1,当x为int32类型时,必须为x尾轴大小的8倍。 | ||
| 112 | +- <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品/Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>: | ||
| 113 | + - 入参`x`仅支持INT4、INT8。 | ||
| 114 | + - 入参`scale`、`offset`仅支持一维,且只能等于x尾轴大小或1,当x为int32类型时,必须为x尾轴大小的8倍。 | ||
| 115 | + | ||
| 116 | +## 约束说明 | ||
| 117 | + | ||
| 118 | +无 | ||
| 119 | + | ||
| 120 | + | ||
| 121 | +## 调用说明 | ||
| 122 | + | ||
| 123 | +| 调用方式 | 样例代码 | 说明 | | ||
| 124 | +| ---------------- | --------------------------- | --------------------------------------------------- | | ||
| 125 | +| aclnn接口 | [test_aclnn_ascend_anti_quant](examples/test_aclnn_ascend_anti_quant.cpp) | 通过[aclnnAscendAntiQuant](docs/aclnnAscendAntiQuant.md)接口方式调用AscendAntiQuantV2算子。 | | ||
| 126 | +| 图模式 | - | 通过[算子IR](op_graph/ascend_anti_quant_v2_proto.h)构图方式调用AscendAntiQuantV2算子。 | | ||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | |产品 | 是否支持 | | 7 | |产品 | 是否支持 | |
| 8 | |:-------------------------|:----------:| | 8 | |:-------------------------|:----------:| |
| 9 | -| <term>Ascend 950PR/Ascend 950DT</term> | × | | 9 | +| <term>Ascend 950PR/Ascend 950DT</term> | √ | |
| 10 | | <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ | | 10 | | <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ | |
| 11 | | <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term> | √ | | 11 | | <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term> | √ | |
| 12 | | <term>Atlas 200I/500 A2 推理产品</term> | × | | 12 | | <term>Atlas 200I/500 A2 推理产品</term> | × | |
| @@ -17,16 +17,28 @@ | |||
| 17 | 17 | ||
| 18 | - 接口功能:根据输入的scale和offset对输入x进行反量化。 | 18 | - 接口功能:根据输入的scale和offset对输入x进行反量化。 |
| 19 | - 计算公式: | 19 | - 计算公式: |
| 20 | - - sqrtMode为false时,计算公式为: | 20 | + - sqrtMode为true,offset为None时,计算公式为: |
| 21 | 21 | ||
| 22 | $$ | 22 | $$ |
| 23 | - y = float16((x+offset) * scale) | 23 | + y = cast\_to\_dst\_type((x) * scale * scale) |
| 24 | $$ | 24 | $$ |
| 25 | 25 | ||
| 26 | - - sqrtMode为true时,计算公式为: | 26 | + - sqrtMode为true,offset不为None时,计算公式为: |
| 27 | 27 | ||
| 28 | $$ | 28 | $$ |
| 29 | - y = float16((x+offset) * scale * scale) | 29 | + y = cast\_to\_dst\_type((x + offset) * scale * scale) |
| 30 | + $$ | ||
| 31 | + | ||
| 32 | + - sqrtMode为false,offset为None时,计算公式为: | ||
| 33 | + | ||
| 34 | + $$ | ||
| 35 | + y = cast\_to\_dst\_type((x) * scale) | ||
| 36 | + $$ | ||
| 37 | + | ||
| 38 | + - sqrtMode为false,offset不为None时,计算公式为: | ||
| 39 | + | ||
| 40 | + $$ | ||
| 41 | + y = cast\_to\_dst\_type((x + offset) * scale) | ||
| 30 | $$ | 42 | $$ |
| 31 | 43 | ||
| 32 | ## 函数原型 | 44 | ## 函数原型 |
| @@ -82,9 +94,9 @@ aclnnStatus aclnnAscendAntiQuant( | |||
| 82 | <tr> | 94 | <tr> |
| 83 | <td>x(aclTensor*)</td> | 95 | <td>x(aclTensor*)</td> |
| 84 | <td>输入</td> | 96 | <td>输入</td> |
| 85 | - <td>表示需要做反量化的输入。对应公式中的`x`。</td> | 97 | + <td>表示需要做反量化的输入。对应公式中的x。</td> |
| 86 | - <td><ul><li>支持空Tensor。</li><li>当数据类型是INT32时,每个数据被作为8个INT4数据使用。</li><li>当数据类型是INT4时,shape的尾轴为偶数。</li></ul></td> | 98 | + <td><ul><li>支持空Tensor;</li><li>当数据类型是INT32时,每个数据被作为8个INT4数据使用;</li><li>当数据类型是INT4时,shape的尾轴为偶数。</li></ul></td> |
| 87 | - <td>INT4、INT8、INT32</td> | 99 | + <td>INT4、INT8、INT32、HIFLOAT8、FLOAT8_E4M3、FLOAT8_E5M2</td> |
| 88 | <td>ND</td> | 100 | <td>ND</td> |
| 89 | <td>0-8</td> | 101 | <td>0-8</td> |
| 90 | <td>√</td> | 102 | <td>√</td> |
| @@ -92,26 +104,26 @@ aclnnStatus aclnnAscendAntiQuant( | |||
| 92 | <tr> | 104 | <tr> |
| 93 | <td>scale(aclTensor*)</td> | 105 | <td>scale(aclTensor*)</td> |
| 94 | <td>输入</td> | 106 | <td>输入</td> |
| 95 | - <td>反量化中的scale值。对应公式中的`scale`。</td> | 107 | + <td>反量化中的scale值。对应公式中的scale。</td> |
| 96 | - <td><ul><li>支持空Tensor。</li><li>shape的大小可以为1,如果不为1,在输入`x`为INT4/INT8类型时,等于输入`x`的最后一个维度的大小;在输入`x`为INT32类型时,等于输入`x`的最后一个维度大小的8倍。</li></ul></td> | 108 | + <td><ul><li>不支持空Tensor;</li><li>scale的维数必须与x相同,或者是1维;</li><li>如果x是1维,scale的形状必须是[1]或与x相同;</li><li>如果scale是1维,其大小必须是1、x[-1]或x[-2];</li><li>如果scale是多维,最多只能有一个非1的维度,且这个非1的维度只能是-1或-2轴;</li><li>当输入x为INT32类型且反量化轴为尾轴时,scale的尾轴需要等于x尾轴大小的8倍;</li><li>当x的类型为HIFLOAT8、FLOAT8_E4M3、FLOAT8_E5M2时,scale只支持FLOAT32。</li></ul></td> |
| 97 | <td>FLOAT32、BFLOAT16</td> | 109 | <td>FLOAT32、BFLOAT16</td> |
| 98 | <td>ND</td> | 110 | <td>ND</td> |
| 99 | - <td>1</td> | 111 | + <td>1-8</td> |
| 100 | <td>√</td> | 112 | <td>√</td> |
| 101 | </tr> | 113 | </tr> |
| 102 | <tr> | 114 | <tr> |
| 103 | <td>offset(aclTensor*)</td> | 115 | <td>offset(aclTensor*)</td> |
| 104 | <td>输入</td> | 116 | <td>输入</td> |
| 105 | - <td>反量化中的offset值。对应公式中的`offset`。</td> | 117 | + <td>反量化中的offset值。对应公式中的offset。</td> |
| 106 | - <td><ul><li>支持空Tensor。</li><li>数据类型和shape需要与`scale`保持一致。</li></ul></td> | 118 | + <td><ul><li>不支持空Tensor;</li><li>数据类型和shape需要与scale保持一致。</li></ul></td> |
| 107 | <td>FLOAT32、BFLOAT16</td> | 119 | <td>FLOAT32、BFLOAT16</td> |
| 108 | <td>ND</td> | 120 | <td>ND</td> |
| 109 | - <td>1</td> | 121 | + <td>1-8</td> |
| 110 | <td>√</td> | 122 | <td>√</td> |
| 111 | </tr> | 123 | </tr> |
| 112 | <tr> | 124 | <tr> |
| 113 | <td>dstType(int64_t)</td> | 125 | <td>dstType(int64_t)</td> |
| 114 | - <td>输入</td> | 126 | + <td>属性</td> |
| 115 | <td>指定输出的数据类型。</td> | 127 | <td>指定输出的数据类型。</td> |
| 116 | <td>支持取值1、27,分别表示FLOAT16、BFLOAT16。</td> | 128 | <td>支持取值1、27,分别表示FLOAT16、BFLOAT16。</td> |
| 117 | <td>-</td> | 129 | <td>-</td> |
| @@ -121,9 +133,9 @@ aclnnStatus aclnnAscendAntiQuant( | |||
| 121 | </tr> | 133 | </tr> |
| 122 | <tr> | 134 | <tr> |
| 123 | <td>sqrtMode(bool)</td> | 135 | <td>sqrtMode(bool)</td> |
| 124 | - <td>输入</td> | 136 | + <td>属性</td> |
| 125 | - <td>指定scale参与计算的逻辑。对应公式中的`sqrtMode`。</td> | 137 | + <td>指定scale参与计算的逻辑。对应公式中的sqrtMode。</td> |
| 126 | - <td>-</td> | 138 | + <td>当x的数据类型为HIFLOAT8、FLOAT8_E4M3、FLOAT8_E5M2时,sqrtMode为false。</td> |
| 127 | <td>-</td> | 139 | <td>-</td> |
| 128 | <td>-</td> | 140 | <td>-</td> |
| 129 | <td>-</td> | 141 | <td>-</td> |
| @@ -132,8 +144,8 @@ aclnnStatus aclnnAscendAntiQuant( | |||
| 132 | <tr> | 144 | <tr> |
| 133 | <td>y(aclTensor*)</td> | 145 | <td>y(aclTensor*)</td> |
| 134 | <td>输出</td> | 146 | <td>输出</td> |
| 135 | - <td>反量化的计算输出。对应公式中的`y`。</td> | 147 | + <td>反量化的计算输出。对应公式中的y。</td> |
| 136 | - <td><ul><li>支持空Tensor。</li><li>当输入`x`为INT4或INT8类型时,shape与输入`x`一致。</li><li>当输入`x`为INT32类型时,shape尾轴的大小为输入`x`的尾轴大小的8倍。</li></ul></td> | 148 | + <td><ul><li>支持空Tensor。</li><li>当输入x为INT32类型时,shape尾轴的大小为输入x的尾轴大小的8倍,其余情况shape与输入x一致。</li></ul></td> |
| 137 | <td>FLOAT16、BFLOAT16</td> | 149 | <td>FLOAT16、BFLOAT16</td> |
| 138 | <td>ND</td> | 150 | <td>ND</td> |
| 139 | <td>0-8</td> | 151 | <td>0-8</td> |
| @@ -167,6 +179,10 @@ aclnnStatus aclnnAscendAntiQuant( | |||
| 167 | - 入参`x`仅支持INT8。 | 179 | - 入参`x`仅支持INT8。 |
| 168 | - 入参`scale`、`offset`和出参`y`不支持BFLOAT16。 | 180 | - 入参`scale`、`offset`和出参`y`不支持BFLOAT16。 |
| 169 | - 入参`dstType`仅支持取值1,表示FLOAT16。 | 181 | - 入参`dstType`仅支持取值1,表示FLOAT16。 |
| 182 | + - 入参`scale`、`offset`仅支持一维,且只能等于x尾轴大小或1,当x为int32类型时,必须为x尾轴大小的8倍。 | ||
| 183 | + - <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品/Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>: | ||
| 184 | + - 入参`x`仅支持INT4、INT8、INT32。 | ||
| 185 | + - 入参`scale`、`offset`仅支持一维,且只能等于x尾轴大小或1,当x为int32类型时,必须为x尾轴大小的8倍。 | ||
| 170 | 186 | ||
| 171 | - **返回值:** | 187 | - **返回值:** |
| 172 | 188 | ||
| @@ -201,9 +217,9 @@ aclnnStatus aclnnAscendAntiQuant( | |||
| 201 | <td>dstType不在有效取值范围。</td> | 217 | <td>dstType不在有效取值范围。</td> |
| 202 | </tr> | 218 | </tr> |
| 203 | <tr> | 219 | <tr> |
| 204 | - <td>x的数据类型为INT4时,x的shape尾轴大小不是偶数。</tr> | 220 | + <td>x的数据类型为INT4时,x的反量化轴大小不是偶数。</tr> |
| 205 | <tr> | 221 | <tr> |
| 206 | - <td>x的数据类型为INT32时,y的shape尾轴不是x的shape尾轴大小的8倍,或者x与y的shape的非尾轴的大小不一致。</td> | 222 | + <td>x的数据类型为INT32时,y的反量化轴不是x的反量化轴大小的8倍,或者x与y的其他轴大小不一致。</td> |
| 207 | </tr> | 223 | </tr> |
| 208 | </tbody></table> | 224 | </tbody></table> |
| 209 | 225 | ||
| @@ -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. |
| @@ -15,31 +15,39 @@ | |||
| 15 | 15 | ||
| 16 | namespace ge { | 16 | namespace ge { |
| 17 | /** | 17 | /** |
| 18 | -* @brief Anti quantizes the input . | 18 | +* @brief Anti quantizes the input. \n |
| 19 | 19 | ||
| 20 | * @par Inputs: | 20 | * @par Inputs: |
| 21 | -* @li x: A multi-dimensional tensor of type int8/int4, specifying the input. | 21 | +* @li x: A required Tensor. Must be one of the following types: int8, int4, hifloat8, float8_e5m2, float8_e4m3. |
| 22 | - The maximum dimension should not exceed 8 dimensions. Format support ND. | 22 | +* The format support ND. Shape support 1D ~ 8D. Specifying the input. |
| 23 | -* @li scale: A 1-D tensor of type float32/bfloat16, specifying the scale. | 23 | +* @li scale: A required Tensor. Must be one of the following types: float32, bfloat16. |
| 24 | - Shape is (n,), where n can be 1. If n is not 1, it must be the same as | 24 | +* The format support ND. Shape support 1D ~ 8D. Specifying the scaling ratio. |
| 25 | - the size of last dimension of x. Format support ND. | 25 | +* @li offset: An optional Tensor. Must be one of the following types: float32, bfloat16. |
| 26 | -* @li offset: A optional 1-D tensor of type float32/bfloat16, specifying the offset. | 26 | +* The format support ND. Shape support 1D ~ 8D. Shape and dataType is same as "scale". Specifying the offset. \n |
| 27 | - The shape and dtype of offset should be same to scale. Format support ND. | ||
| 28 | 27 | ||
| 29 | * @par Attributes: | 28 | * @par Attributes: |
| 30 | * @li dst_type: A optional int32, specifying the output data type. Defaults to "DT_FLOAT16". | 29 | * @li dst_type: A optional int32, specifying the output data type. Defaults to "DT_FLOAT16". |
| 31 | -* @li sqrt_mode: A optional bool, specifying whether to perform square root on "scale", either "True" or "False". | 30 | +* @li sqrt_mode: A optional bool, specifying whether to perform square root on "scale", either "true" or "false". |
| 32 | -* Defaults to "False" . \n | 31 | +* Defaults to "false" . \n |
| 32 | + | ||
| 33 | +* @attention Constraints: | ||
| 34 | +* @li When dst_type of x is DT_INT4, the last axis of its shape is even. | ||
| 35 | +# @li When the data type of x is DT_HIFLOAT8, DT_FLOAT8_E5M2, or DT_FLOAT8_E4M3, scale is only supported for DT_FLOAT. | ||
| 36 | +# @li When the data type of x is DT_HIFLOAT8, DT_FLOAT8_E5M2, or DT_FLOAT8_E4M3, sqrt_mode must be "false". | ||
| 37 | +* @li The dimensionality of scale must match that of x, or be 1-dimensional. The shape of scale must satisfy the following constraints: \n | ||
| 38 | +* - If x is 1-dim, the shape of scale must be [1] or the same as x. | ||
| 39 | +* - If scale is 1-dim, its size must be either 1, x[-1] or x[-2]. | ||
| 40 | +# - If scale is multi-dim, it can have at most one non-d dimension, and that dimension must be along the -1st or -2nd axis of x. | ||
| 33 | 41 | ||
| 34 | * @par Outputs: | 42 | * @par Outputs: |
| 35 | -* y: The dequantized output tensor of type float16 or bfloat16. \n | 43 | +* y: The dequantized output tensor of type float16 or bfloat16. The format support ND. |
| 36 | - | 44 | +* Shape support 1D ~ 8D. Has the same shape as input "x". Dtype should be the same as the attribute dst_type. \n |
| 37 | */ | 45 | */ |
| 38 | REG_OP(AscendAntiQuantV2) | 46 | REG_OP(AscendAntiQuantV2) |
| 39 | - .INPUT(x, TensorType({DT_INT8, DT_INT4})) | 47 | + .INPUT(x, TensorType({DT_INT8, DT_INT4, DT_HIFLOAT8, DT_FLOAT8_E5M2, DT_FLOAT8_E4M3FN})) |
| 40 | - .INPUT(scale, TensorType({DT_FLOAT, DT_BFLOAT16})) | 48 | + .INPUT(scale, TensorType({DT_FLOAT, DT_BF16})) |
| 41 | - .OPTIONAL_INPUT(offset, TensorType({DT_FLOAT, DT_BFLOAT16})) | 49 | + .OPTIONAL_INPUT(offset, TensorType({DT_FLOAT, DT_BF16})) |
| 42 | - .OUTPUT(y, TensorType({DT_FLOAT16, DT_BFLOAT16})) | 50 | + .OUTPUT(y, TensorType({DT_FLOAT16, DT_BF16})) |
| 43 | .ATTR(dst_type, Int, DT_FLOAT16) | 51 | .ATTR(dst_type, Int, DT_FLOAT16) |
| 44 | .ATTR(sqrt_mode, Bool, false) | 52 | .ATTR(sqrt_mode, Bool, false) |
| 45 | .OP_END_FACTORY_REG(AscendAntiQuantV2) | 53 | .OP_END_FACTORY_REG(AscendAntiQuantV2) |
| @@ -0,0 +1,68 @@ | |||
| 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 ascend_anti_quant_v2.cpp | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | +namespace ops { | ||
| 18 | +static const std::vector<ge::DataType> INPUT_DATA_TYPE = {ge::DT_INT8, ge::DT_INT8, ge::DT_INT8, ge::DT_INT8, ge::DT_INT4, ge::DT_INT4, ge::DT_INT4, ge::DT_INT4, | ||
| 19 | + ge::DT_HIFLOAT8, ge::DT_HIFLOAT8, ge::DT_FLOAT8_E5M2, ge::DT_FLOAT8_E5M2, ge::DT_FLOAT8_E4M3FN, ge::DT_FLOAT8_E4M3FN}; | ||
| 20 | + | ||
| 21 | +static const std::vector<ge::DataType> INPUT_SCALE_DATA_TYPE = {ge::DT_FLOAT, ge::DT_FLOAT, ge::DT_BF16, ge::DT_BF16, ge::DT_FLOAT, ge::DT_FLOAT, ge::DT_BF16, ge::DT_BF16, | ||
| 22 | + ge::DT_FLOAT, ge::DT_FLOAT, ge::DT_FLOAT, ge::DT_FLOAT, ge::DT_FLOAT, ge::DT_FLOAT}; | ||
| 23 | + | ||
| 24 | +static const std::vector<ge::DataType> OUTPUT_DATA_TYPE = {ge::DT_FLOAT16, ge::DT_BF16, ge::DT_FLOAT16, ge::DT_BF16, ge::DT_FLOAT16, ge::DT_BF16, ge::DT_FLOAT16, ge::DT_BF16, | ||
| 25 | + ge::DT_FLOAT16, ge::DT_BF16, ge::DT_FLOAT16, ge::DT_BF16, ge::DT_FLOAT16, ge::DT_BF16}; | ||
| 26 | + | ||
| 27 | +static const std::vector<ge::Format> FORMAT = {ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, | ||
| 28 | + ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND}; | ||
| 29 | + | ||
| 30 | +class AscendAntiQuantV2 : public OpDef { | ||
| 31 | +public: | ||
| 32 | + explicit AscendAntiQuantV2(const char* name) : OpDef(name) | ||
| 33 | + { | ||
| 34 | + OpAICoreConfig config; | ||
| 35 | + config.Input("x") | ||
| 36 | + .ParamType(REQUIRED) | ||
| 37 | + .DataType(INPUT_DATA_TYPE) | ||
| 38 | + .Format(FORMAT) | ||
| 39 | + .UnknownShapeFormat(FORMAT); | ||
| 40 | + config.Input("scale") | ||
| 41 | + .ParamType(REQUIRED) | ||
| 42 | + .DataType(INPUT_SCALE_DATA_TYPE) | ||
| 43 | + .Format(FORMAT) | ||
| 44 | + .UnknownShapeFormat(FORMAT); | ||
| 45 | + config.Input("offset") | ||
| 46 | + .ParamType(OPTIONAL) | ||
| 47 | + .DataType(INPUT_SCALE_DATA_TYPE) | ||
| 48 | + .Format(FORMAT) | ||
| 49 | + .UnknownShapeFormat(FORMAT); | ||
| 50 | + config.Output("y") | ||
| 51 | + .ParamType(REQUIRED) | ||
| 52 | + .DataType(OUTPUT_DATA_TYPE) | ||
| 53 | + .Format(FORMAT) | ||
| 54 | + .UnknownShapeFormat(FORMAT); | ||
| 55 | + this->Attr("dst_type").AttrType(OPTIONAL).Int(ge::DT_FLOAT16); | ||
| 56 | + this->Attr("sqrt_mode").AttrType(OPTIONAL).Bool(false); | ||
| 57 | + | ||
| 58 | + config.DynamicCompileStaticFlag(true) | ||
| 59 | + .DynamicRankSupportFlag(true) | ||
| 60 | + .DynamicShapeSupportFlag(true) | ||
| 61 | + .NeedCheckSupportFlag(false) | ||
| 62 | + .ExtendCfgInfo("opFile.value", "ascend_anti_quant_v2_apt"); | ||
| 63 | + this->AICore().AddConfig("ascend950", config); | ||
| 64 | + } | ||
| 65 | +}; | ||
| 66 | + | ||
| 67 | +OP_ADD(AscendAntiQuantV2); | ||
| 68 | +} // namespace ops | ||
| @@ -0,0 +1,47 @@ | |||
| 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 ascend_quant_v2.cc | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | +using namespace ge; | ||
| 19 | +namespace ops { | ||
| 20 | +constexpr size_t g_AttrDstType = 0; | ||
| 21 | + | ||
| 22 | +static graphStatus InferShapeForAscendAntiQuantV2(gert::InferShapeContext* context) | ||
| 23 | +{ | ||
| 24 | + OP_LOGD(context->GetNodeName(), "Begin to do InferShapeForAscendAntiQuantV2"); | ||
| 25 | + const gert::Shape* inputXShape = context->GetInputShape(0); | ||
| 26 | + OP_CHECK_NULL_WITH_CONTEXT(context, inputXShape); | ||
| 27 | + | ||
| 28 | + gert::Shape* outputShape = context->GetOutputShape(0); | ||
| 29 | + | ||
| 30 | + *outputShape = *inputXShape; | ||
| 31 | + OP_LOGD(context->GetNodeName(), "End to do InferShapeForAscendAntiQuantV2"); | ||
| 32 | + return ge::GRAPH_SUCCESS; | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +static ge::graphStatus InferDataTypeForAscendAntiQuantV2(gert::InferDataTypeContext* context) | ||
| 36 | +{ | ||
| 37 | + OP_LOGD(context->GetNodeName(), "Begin to do InferDataTypeForAscendAntiQuantV2"); | ||
| 38 | + const int32_t* dstDtype = context->GetAttrs()->GetAttrPointer<int32_t>(g_AttrDstType); | ||
| 39 | + OP_CHECK_NULL_WITH_CONTEXT(context, dstDtype); | ||
| 40 | + ge::DataType outDtype = static_cast<ge::DataType>(*dstDtype); | ||
| 41 | + context->SetOutputDataType(0, outDtype); | ||
| 42 | + OP_LOGD(context->GetNodeName(), "End to do InferDataTypeForAscendAntiQuantV2"); | ||
| 43 | + return ge::GRAPH_SUCCESS; | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +IMPL_OP_INFERSHAPE(AscendAntiQuantV2).InferShape(InferShapeForAscendAntiQuantV2).InferDataType(InferDataTypeForAscendAntiQuantV2); | ||
| 47 | +} // namespace ops | ||
| @@ -0,0 +1,810 @@ | |||
| 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 ascend_quant_v2_regbase_tiling.cc | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | +using namespace std; | ||
| 20 | +using namespace ge; | ||
| 21 | +using namespace AscendC; | ||
| 22 | +using namespace AscendAntiQuantV2Op; | ||
| 23 | + | ||
| 24 | +namespace optiling { | ||
| 25 | +constexpr size_t INPUT_X_INDEX = 0; | ||
| 26 | +constexpr size_t INPUT_SCALE_INDEX = 1; | ||
| 27 | +constexpr size_t INPUT_OFFSET_INDEX = 2; | ||
| 28 | +constexpr size_t ATTR_DST_TYPE_INDEX = 0; | ||
| 29 | +constexpr size_t ATTR_SQRT_MODE_INDEX = 1; | ||
| 30 | +constexpr size_t SYNC_WORKSPACE_SIZE = 16777216; | ||
| 31 | +constexpr int64_t CACHE_SIZE_950 = 128; | ||
| 32 | +constexpr int64_t g_BaseLen = 128; | ||
| 33 | +constexpr int64_t g_BlockSize = 32; | ||
| 34 | +constexpr int64_t g_HalfBase = 2; | ||
| 35 | +constexpr int32_t g_AxisMax = 2; | ||
| 36 | +constexpr size_t g_FirstShapeDim = 0; | ||
| 37 | +constexpr size_t g_SecondShapeDim = 1; | ||
| 38 | +constexpr size_t g_ThirdShapeDim = 2; | ||
| 39 | +constexpr int64_t FP32_BYTE_SIZE = 4; | ||
| 40 | +constexpr int64_t FP16_BYTE_SIZE = 2; | ||
| 41 | +static constexpr int64_t INT4_NUMS_IN_INT8_SPACE = 2; | ||
| 42 | +constexpr int64_t DEFAULT_BASE_LEN = 128; | ||
| 43 | +constexpr int64_t LAST_DIM_NUM = 128; | ||
| 44 | +constexpr int64_t BUFF_NUM = 2; | ||
| 45 | +static const gert::Shape g_vec_1_shape = {1}; | ||
| 46 | +static const gert::Shape g_vec_8_shape = {8}; | ||
| 47 | + | ||
| 48 | +const gert::Shape& AscendAntiQuantV2Regbase::EnsureXAndScaleNotScalar(const gert::Shape& inShape) | ||
| 49 | +{ | ||
| 50 | + if (inShape.IsScalar()) { | ||
| 51 | + return g_vec_1_shape; | ||
| 52 | + } | ||
| 53 | + return inShape; | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +const gert::Shape& AscendAntiQuantV2Regbase::EnsureYNotScalar(const gert::Shape& inShape) | ||
| 57 | +{ | ||
| 58 | + if (inShape.IsScalar()) { | ||
| 59 | + return g_vec_8_shape; | ||
| 60 | + } | ||
| 61 | + return inShape; | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | +ge::graphStatus AscendAntiQuantV2Regbase::DoAscendAntiQuantV2Tiling() | ||
| 65 | +{ | ||
| 66 | + OP_CHECK_IF( | ||
| 67 | + (GetCompileInfo() != ge::GRAPH_SUCCESS), | ||
| 68 | + OP_LOGE(context_->GetNodeName(), "DoAscendAntiQuantV2Tiling GetCompileInfo Failed."), return ge::GRAPH_FAILED); | ||
| 69 | + OP_CHECK_IF( | ||
| 70 | + (GetOpParam() != ge::GRAPH_SUCCESS), | ||
| 71 | + OP_LOGE(context_->GetNodeName(), "DoAscendAntiQuantV2Tiling GetOpParam Failed."), return ge::GRAPH_FAILED); | ||
| 72 | + | ||
| 73 | + CalcTiling(); | ||
| 74 | + CalcTilingKey(); | ||
| 75 | + return WriteTilingData(); | ||
| 76 | +} | ||
| 77 | + | ||
| 78 | +ge::graphStatus AscendAntiQuantV2Regbase::GetCompileInfo() | ||
| 79 | +{ | ||
| 80 | + auto compileInfo = context_->GetCompileInfo<AscendAntiQuantV2CompileInfo>(); | ||
| 81 | + OP_CHECK_NULL_WITH_CONTEXT(context_, compileInfo); | ||
| 82 | + coreNum_ = compileInfo->vectorCoreNum; | ||
| 83 | + ubSize_ = compileInfo->ubSize; | ||
| 84 | + OP_CHECK_IF( | ||
| 85 | + (coreNum_ <= 0 || ubSize_ <= 0), | ||
| 86 | + OP_LOGE( | ||
| 87 | + context_->GetNodeName(), "AscendAntiQuantV2 GetCompileInfo Failed, coreNum:%ld, ubSize:%lu.", coreNum_, | ||
| 88 | + ubSize_), | ||
| 89 | + return ge::GRAPH_FAILED); | ||
| 90 | + cacheLine_ = CACHE_SIZE_950; | ||
| 91 | + return ge::GRAPH_SUCCESS; | ||
| 92 | +} | ||
| 93 | + | ||
| 94 | +ge::graphStatus AscendAntiQuantV2Regbase::CheckInputDtype() | ||
| 95 | +{ | ||
| 96 | + auto xInputDesc = context_->GetInputDesc(INPUT_X_INDEX); | ||
| 97 | + OP_CHECK_NULL_WITH_CONTEXT(context_, xInputDesc); | ||
| 98 | + xDtype_ = xInputDesc->GetDataType(); | ||
| 99 | + | ||
| 100 | + auto scaleInputDesc = context_->GetInputDesc(INPUT_SCALE_INDEX); | ||
| 101 | + OP_CHECK_NULL_WITH_CONTEXT(context_, scaleInputDesc); | ||
| 102 | + scaleDtype_ = scaleInputDesc->GetDataType(); | ||
| 103 | + | ||
| 104 | + auto yInputDesc = context_->GetOutputDesc(0); | ||
| 105 | + OP_CHECK_NULL_WITH_CONTEXT(context_, yInputDesc); | ||
| 106 | + yDtype_ = yInputDesc->GetDataType(); | ||
| 107 | + | ||
| 108 | + if (hasOffset_) { | ||
| 109 | + auto offsetInputDesc = context_->GetInputDesc(INPUT_OFFSET_INDEX); | ||
| 110 | + OP_CHECK_NULL_WITH_CONTEXT(context_, offsetInputDesc); | ||
| 111 | + auto offsetDtype = offsetInputDesc->GetDataType(); | ||
| 112 | + | ||
| 113 | + OP_CHECK_IF( | ||
| 114 | + scaleDtype_ != offsetDtype, | ||
| 115 | + OP_LOGE( | ||
| 116 | + context_->GetNodeName(), "input scale dtype %s is not same as input offset dtype %s", | ||
| 117 | + Ops::Base::ToString(scaleDtype_).c_str(), Ops::Base::ToString(offsetDtype).c_str()), | ||
| 118 | + return ge::GRAPH_FAILED); | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + if (xDtype_ == ge::DT_HIFLOAT8 || xDtype_ == ge::DT_FLOAT8_E5M2 || xDtype_ == ge::DT_FLOAT8_E4M3FN) { | ||
| 122 | + OP_CHECK_IF( | ||
| 123 | + scaleDtype_ != ge::DT_FLOAT, | ||
| 124 | + OP_LOGE( | ||
| 125 | + context_->GetNodeName(), "when x is of type %s, the scale must be type FP32", Ops::Base::ToString(xDtype_).c_str()), | ||
| 126 | + return ge::GRAPH_FAILED); | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + return ge::GRAPH_SUCCESS; | ||
| 130 | +} | ||
| 131 | + | ||
| 132 | +ge::graphStatus AscendAntiQuantV2Regbase::CheckInputValid( | ||
| 133 | + const gert::Shape& input1, const gert::Shape& input2, const std::string& param) const | ||
| 134 | +{ | ||
| 135 | + size_t input1DimNum = input1.GetDimNum(); | ||
| 136 | + size_t input2DimNum = input2.GetDimNum(); | ||
| 137 | + if (static_cast<int32_t>(input1DimNum) != static_cast<int32_t>(input2DimNum) && | ||
| 138 | + static_cast<int32_t>(input2DimNum) != 1) { | ||
| 139 | + OP_LOGE( | ||
| 140 | + context_->GetNodeName(), "the dimension(%zu) of %s is invalid, should be same as x(%zu) or 1", input2DimNum, | ||
| 141 | + param.c_str(), input1DimNum); | ||
| 142 | + return ge::GRAPH_FAILED; | ||
| 143 | + } | ||
| 144 | + | ||
| 145 | + if (input1DimNum == static_cast<size_t>(1) && input2.GetDim(0) != 1 && input2.GetDim(0) != input1.GetDim(0)) { | ||
| 146 | + OP_LOGE( | ||
| 147 | + context_->GetNodeName(), | ||
| 148 | + "when the dim of x is 1, the shape of %s must be either 1 or the same as x", param.c_str()); | ||
| 149 | + return ge::GRAPH_FAILED; | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + if (input1DimNum > 1) { | ||
| 153 | + if (input2DimNum == static_cast<size_t>(1) && input2.GetDim(0) != input1.GetDim(input1DimNum - 1) && | ||
| 154 | + input2.GetDim(0) != input1.GetDim(input1DimNum - 2) && input2.GetDim(0) != 1) { | ||
| 155 | + OP_LOGE( | ||
| 156 | + context_->GetNodeName(), | ||
| 157 | + "when the dim of %s is 1, its shape must be either 1, or match the -1 or -2 dim of x", param.c_str()); | ||
| 158 | + return ge::GRAPH_FAILED; | ||
| 159 | + } | ||
| 160 | + if (input2DimNum > static_cast<size_t>(1)) { | ||
| 161 | + size_t input2Axis = (input2.GetDim(input2DimNum - 2) != 1 ? input2DimNum - 2 : input2DimNum - 1); | ||
| 162 | + auto input2Size = input2.GetShapeSize(); | ||
| 163 | + if (input2Size != input2.GetDim(input2Axis)) { | ||
| 164 | + OP_LOGE( | ||
| 165 | + context_->GetNodeName(), | ||
| 166 | + "the %s can have at most one dimension that is not 1.", param.c_str()); | ||
| 167 | + return ge::GRAPH_FAILED; | ||
| 168 | + } | ||
| 169 | + } | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + return ge::GRAPH_SUCCESS; | ||
| 173 | +} | ||
| 174 | + | ||
| 175 | +ge::graphStatus AscendAntiQuantV2Regbase::CheckOutputValid(const gert::Shape& input, const gert::Shape& output) const | ||
| 176 | +{ | ||
| 177 | + size_t inputDimNum = input.GetDimNum(); | ||
| 178 | + size_t outputDimNum = output.GetDimNum(); | ||
| 179 | + OP_CHECK_IF( | ||
| 180 | + inputDimNum != outputDimNum, OP_LOGE(context_->GetNodeName(), "x dim and y dim must be same."), return ge::GRAPH_FAILED); | ||
| 181 | + | ||
| 182 | + for (uint32_t i = 0; i < inputDimNum; i++) { | ||
| 183 | + OP_CHECK_IF(input.GetDim(i) != output.GetDim(i), OP_LOGE(context_->GetNodeName(), | ||
| 184 | + "x shape and y shape must be same."), return ge::GRAPH_FAILED); | ||
| 185 | + } | ||
| 186 | + | ||
| 187 | + return ge::GRAPH_SUCCESS; | ||
| 188 | +} | ||
| 189 | + | ||
| 190 | +ge::graphStatus AscendAntiQuantV2Regbase::CheckShapeEqual(const gert::Shape& shape1, const gert::Shape& shape2) const | ||
| 191 | +{ | ||
| 192 | + size_t x1DimNum = shape1.GetDimNum(); | ||
| 193 | + size_t x2DimNum = shape2.GetDimNum(); | ||
| 194 | + OP_CHECK_IF( | ||
| 195 | + x1DimNum != x2DimNum, OP_LOGE(context_->GetNodeName(), "scale shape and offset shape must be same."), | ||
| 196 | + return ge::GRAPH_FAILED); | ||
| 197 | + for (uint32_t i = 0; i < x1DimNum; i++) { | ||
| 198 | + OP_CHECK_IF( | ||
| 199 | + shape1.GetDim(i) != shape2.GetDim(i), | ||
| 200 | + OP_LOGE(context_->GetNodeName(), "scale shape and offset shape must be same."), return ge::GRAPH_FAILED); | ||
| 201 | + } | ||
| 202 | + return ge::GRAPH_SUCCESS; | ||
| 203 | +} | ||
| 204 | + | ||
| 205 | +ge::graphStatus AscendAntiQuantV2Regbase::CheckAttrs(const gert::Shape& xShape) | ||
| 206 | +{ | ||
| 207 | + auto* attrs = context_->GetAttrs(); | ||
| 208 | + OP_CHECK_NULL_WITH_CONTEXT(context_, attrs); | ||
| 209 | + // get dstType | ||
| 210 | + const int32_t* dstType = attrs->GetAttrPointer<int32_t>(ATTR_DST_TYPE_INDEX); | ||
| 211 | + OP_CHECK_NULL_WITH_CONTEXT(context_, dstType); | ||
| 212 | + dstType_ = *dstType; | ||
| 213 | + // get sqrtMode | ||
| 214 | + const auto* sqrtMode = attrs->GetAttrPointer<bool>(ATTR_SQRT_MODE_INDEX); | ||
| 215 | + OP_CHECK_NULL_WITH_CONTEXT(context_, sqrtMode); | ||
| 216 | + sqrtMode_ = static_cast<int16_t>(*sqrtMode); | ||
| 217 | + | ||
| 218 | + int32_t xDimNum = static_cast<int32_t>(xShape.GetDimNum()); | ||
| 219 | + | ||
| 220 | + // check dstType and output dtype, must be same | ||
| 221 | + if (dstType_ != ge::DT_FLOAT16 && dstType_ != ge::DT_BF16) { | ||
| 222 | + OP_LOGE( | ||
| 223 | + context_->GetNodeName(), "dst type:%s is invalid", | ||
| 224 | + Ops::Base::ToString(static_cast<ge::DataType>(dstType_)).c_str()); | ||
| 225 | + return ge::GRAPH_FAILED; | ||
| 226 | + } | ||
| 227 | + if (dstType_ != yDtype_) { | ||
| 228 | + OP_LOGE( | ||
| 229 | + context_->GetNodeName(), "dst type:%s not equal output y dtype:%s", | ||
| 230 | + Ops::Base::ToString(static_cast<ge::DataType>(dstType_)).c_str(), Ops::Base::ToString(yDtype_).c_str()); | ||
| 231 | + return ge::GRAPH_FAILED; | ||
| 232 | + } | ||
| 233 | + if (xDtype_ == ge::DT_INT4 && (xShape.GetDim(xDimNum - 1) % INT4_NUMS_IN_INT8_SPACE)) { | ||
| 234 | + OP_LOGE( | ||
| 235 | + context_->GetNodeName(), "if xDtype represents DT_INT4, x last dim:%ld must be divisible by 2", | ||
| 236 | + xShape.GetDim(xDimNum - 1)); | ||
| 237 | + return ge::GRAPH_FAILED; | ||
| 238 | + } | ||
| 239 | + if (xDtype_ == ge::DT_HIFLOAT8 || xDtype_ == ge::DT_FLOAT8_E5M2 || xDtype_ == ge::DT_FLOAT8_E4M3FN) { | ||
| 240 | + OP_CHECK_IF( | ||
| 241 | + sqrtMode_ != 0, | ||
| 242 | + OP_LOGE( | ||
| 243 | + context_->GetNodeName(), "when x is of type %s, sqrtMode must be False", Ops::Base::ToString(xDtype_).c_str()), | ||
| 244 | + return ge::GRAPH_FAILED); | ||
| 245 | + } | ||
| 246 | + | ||
| 247 | + return ge::GRAPH_SUCCESS; | ||
| 248 | +} | ||
| 249 | + | ||
| 250 | +void AscendAntiQuantV2Regbase::MergeInputShape(const gert::Shape& input) | ||
| 251 | +{ | ||
| 252 | + int64_t shape0 = 1; | ||
| 253 | + int64_t shape1 = static_cast<int64_t>(input.GetDim(input.GetDimNum() - 1)); | ||
| 254 | + int64_t shape2 = 1; | ||
| 255 | + if (mode_ == static_cast<uint32_t>(TPL_PER_TENSOR)) { | ||
| 256 | + // pertensor merge [1, x0*x1...*xn, 1] | ||
| 257 | + for (size_t idx = 0; idx < static_cast<size_t>(input.GetDimNum() - 1); ++idx) { | ||
| 258 | + shape1 = shape1 * static_cast<int64_t>(input.GetDim(idx)); | ||
| 259 | + } | ||
| 260 | + } else if (mode_ == static_cast<uint32_t>(TPL_PER_HEAD)) { | ||
| 261 | + // perhead merge [x0*x1...*x(n-2), x(n-1), xn] | ||
| 262 | + for (size_t idx = 0; idx < static_cast<size_t>(input.GetDimNum() - 2); ++idx) { | ||
| 263 | + shape0 = shape0 * input.GetDim(idx); | ||
| 264 | + } | ||
| 265 | + shape1 = input.GetDim(input.GetDimNum() - 2); | ||
| 266 | + shape2 = input.GetDim(input.GetDimNum() - 1); | ||
| 267 | + } else { | ||
| 268 | + // perchannel merge [x0*x1*...*x(n-1), xn, 1] | ||
| 269 | + for (size_t idx = 0; idx < static_cast<size_t>(input.GetDimNum() - 1); ++idx) { | ||
| 270 | + shape0 = shape0 * input.GetDim(idx); | ||
| 271 | + } | ||
| 272 | + } | ||
| 273 | + // last dim is 1, perhead is perchannel | ||
| 274 | + if (mode_ == static_cast<uint32_t>(TPL_PER_HEAD) && shape2 == 1) { | ||
| 275 | + mode_ = static_cast<decltype(mode_)>(TPL_PER_CHANNEL); | ||
| 276 | + } | ||
| 277 | + // merge shape to 3 dim | ||
| 278 | + xInputShape_.SetDimNum(3); | ||
| 279 | + xInputShape_.SetDim(g_FirstShapeDim, shape0); | ||
| 280 | + xInputShape_.SetDim(g_SecondShapeDim, shape1); | ||
| 281 | + xInputShape_.SetDim(g_ThirdShapeDim, shape2); | ||
| 282 | + OP_LOGI(context_->GetNodeName(), "merge shape0:%ld, shape1:%ld, shape2:%ld", shape0, shape1, shape2); | ||
| 283 | +} | ||
| 284 | + | ||
| 285 | +ge::graphStatus AscendAntiQuantV2Regbase::GetOpParam() | ||
| 286 | +{ | ||
| 287 | + auto xInput = context_->GetInputShape(INPUT_X_INDEX); | ||
| 288 | + OP_CHECK_NULL_WITH_CONTEXT(context_, xInput); | ||
| 289 | + auto scaleInput = context_->GetInputShape(INPUT_SCALE_INDEX); | ||
| 290 | + OP_CHECK_NULL_WITH_CONTEXT(context_, scaleInput); | ||
| 291 | + auto offsetInput = context_->GetOptionalInputShape(INPUT_OFFSET_INDEX); | ||
| 292 | + if (offsetInput == nullptr) { | ||
| 293 | + hasOffset_ = false; | ||
| 294 | + } | ||
| 295 | + auto yOut = context_->GetOutputShape(0); | ||
| 296 | + OP_CHECK_NULL_WITH_CONTEXT(context_, yOut); | ||
| 297 | + | ||
| 298 | + // 不支持空tensor | ||
| 299 | + size_t xSizeNum = xInput->GetStorageShape().GetShapeSize(); | ||
| 300 | + if (xSizeNum == 0ULL) { | ||
| 301 | + OP_LOGE(context_->GetNodeName(), "ascend_anti_quant_v2 does not support empty tensor."); | ||
| 302 | + return ge::GRAPH_FAILED; | ||
| 303 | + } | ||
| 304 | + | ||
| 305 | + OP_CHECK_IF( | ||
| 306 | + (CheckInputDtype() != ge::GRAPH_SUCCESS), OP_LOGE(context_->GetNodeName(), "check input dtype failed."), | ||
| 307 | + return ge::GRAPH_FAILED); | ||
| 308 | + | ||
| 309 | + const gert::Shape& xInputShape = EnsureXAndScaleNotScalar(xInput->GetStorageShape()); | ||
| 310 | + const gert::Shape& scaleInputShape = EnsureXAndScaleNotScalar(scaleInput->GetStorageShape()); | ||
| 311 | + const gert::Shape& yInputShape = EnsureYNotScalar(yOut->GetStorageShape()); | ||
| 312 | + OP_CHECK_IF( | ||
| 313 | + (CheckAttrs(xInputShape) != ge::GRAPH_SUCCESS), OP_LOGE(context_->GetNodeName(), "op attrs is invalid."), | ||
| 314 | + return ge::GRAPH_FAILED); | ||
| 315 | + | ||
| 316 | + // check the shape of the y is valid | ||
| 317 | + OP_CHECK_IF( | ||
| 318 | + (CheckOutputValid(xInputShape, yInputShape) != ge::GRAPH_SUCCESS), | ||
| 319 | + OP_LOGE(context_->GetNodeName(), "x and y is invalid."), return ge::GRAPH_FAILED); | ||
| 320 | + | ||
| 321 | + // check the shape of the scale is valid | ||
| 322 | + OP_CHECK_IF( | ||
| 323 | + (CheckInputValid(xInputShape, scaleInputShape, "scale") != ge::GRAPH_SUCCESS), | ||
| 324 | + OP_LOGE(context_->GetNodeName(), "x and scale is invalid."), return ge::GRAPH_FAILED); | ||
| 325 | + // if offset is not null, check the shape of the offset | ||
| 326 | + if (hasOffset_) { | ||
| 327 | + const gert::Shape& offsetInputShape = EnsureXAndScaleNotScalar(offsetInput->GetStorageShape()); | ||
| 328 | + // check scale and offset is same | ||
| 329 | + OP_CHECK_IF( | ||
| 330 | + (CheckShapeEqual(scaleInputShape, offsetInputShape) != ge::GRAPH_SUCCESS), | ||
| 331 | + OP_LOGE(context_->GetNodeName(), "scale and offset is invalid."), return ge::GRAPH_FAILED); | ||
| 332 | + // check the shape of the offset is valid | ||
| 333 | + OP_CHECK_IF( | ||
| 334 | + (CheckInputValid(xInputShape, offsetInputShape, "offset") != ge::GRAPH_SUCCESS), | ||
| 335 | + OP_LOGE(context_->GetNodeName(), "x and offset is invalid."), return ge::GRAPH_FAILED); | ||
| 336 | + } | ||
| 337 | + // check excute mode | ||
| 338 | + int32_t xDimNum = static_cast<int32_t>(xInputShape.GetDimNum()); | ||
| 339 | + int32_t scaleDimNum = static_cast<int32_t>(scaleInputShape.GetDimNum()); | ||
| 340 | + if (scaleInputShape.GetShapeSize() == 1) { | ||
| 341 | + mode_ = static_cast<decltype(mode_)>(TPL_PER_TENSOR); | ||
| 342 | + } else if (scaleDimNum == 1) { | ||
| 343 | + if (xDimNum > 1 && xInputShape.GetDim(xDimNum - 1) != xInputShape.GetDim(xDimNum - 2) && | ||
| 344 | + scaleInputShape.GetDim(0) == xInputShape.GetDim(xDimNum - 2)) { | ||
| 345 | + mode_ = static_cast<decltype(mode_)>(TPL_PER_HEAD); | ||
| 346 | + } else { | ||
| 347 | + mode_ = static_cast<decltype(mode_)>(TPL_PER_CHANNEL); | ||
| 348 | + } | ||
| 349 | + } else if (scaleDimNum > 1 && scaleInputShape.GetDim(scaleDimNum - 2) != 1) { | ||
| 350 | + mode_ = static_cast<decltype(mode_)>(TPL_PER_HEAD); | ||
| 351 | + } else { | ||
| 352 | + mode_ = static_cast<decltype(mode_)>(TPL_PER_CHANNEL); | ||
| 353 | + } | ||
| 354 | + | ||
| 355 | + MergeInputShape(xInputShape); | ||
| 356 | + return ge::GRAPH_SUCCESS; | ||
| 357 | +} | ||
| 358 | + | ||
| 359 | +uint32_t AscendAntiQuantV2Regbase::GetCoreNum(int64_t factor, int64_t coreNum) const | ||
| 360 | +{ | ||
| 361 | + int64_t elePerCore = Ops::Base::CeilDiv(factor, static_cast<int64_t>(coreNum)); | ||
| 362 | + uint32_t actCore = static_cast<uint32_t>(Ops::Base::CeilDiv(factor, elePerCore)); | ||
| 363 | + return actCore; | ||
| 364 | +} | ||
| 365 | + | ||
| 366 | +int64_t AscendAntiQuantV2Regbase::CalcMaxBaseLen(int64_t ubSize) const | ||
| 367 | +{ | ||
| 368 | + // set n == 1 to calc max base | ||
| 369 | + int64_t xDtypeSize = ge::GetSizeByDataType(ge::DT_INT8); | ||
| 370 | + int64_t yDtypeSize = ge::GetSizeByDataType(yDtype_); | ||
| 371 | + int64_t scaleDtypeSize = ge::GetSizeByDataType(scaleDtype_); | ||
| 372 | + int64_t baseInput = hasOffset_ ? 2 : 1; // hasoffset means 2 input, else means 1 input | ||
| 373 | + if (mode_ == static_cast<int64_t>(TPL_PER_TENSOR)) { | ||
| 374 | + baseInput = 0; | ||
| 375 | + } | ||
| 376 | + int64_t totalBytes = (xDtypeSize + scaleDtypeSize * baseInput + yDtypeSize) * BUFF_NUM; | ||
| 377 | + return totalBytes == 0 ? DEFAULT_BASE_LEN : ubSize / totalBytes; | ||
| 378 | +} | ||
| 379 | + | ||
| 380 | +int64_t AscendAntiQuantV2Regbase::CalcMaxN(int64_t ubSize, int64_t base) const | ||
| 381 | +{ | ||
| 382 | + int64_t xDtypeSize = ge::GetSizeByDataType(ge::DT_INT8); | ||
| 383 | + int64_t yDtypeSize = ge::GetSizeByDataType(yDtype_); | ||
| 384 | + int64_t scaleDtypeSize = ge::GetSizeByDataType(scaleDtype_); | ||
| 385 | + int64_t leftXBytes = ubSize - base * scaleDtypeSize * BUFF_NUM; | ||
| 386 | + if (hasOffset_) { | ||
| 387 | + int64_t offsetDtypeSize = ge::GetSizeByDataType(scaleDtype_); | ||
| 388 | + leftXBytes -= base * offsetDtypeSize * BUFF_NUM; | ||
| 389 | + } | ||
| 390 | + | ||
| 391 | + if (leftXBytes <= 0) { | ||
| 392 | + return 1; | ||
| 393 | + } | ||
| 394 | + | ||
| 395 | + int64_t totalNBytes = xDtypeSize + yDtypeSize; | ||
| 396 | + if (totalNBytes == 0 || base == 0 || BUFF_NUM == 0) { | ||
| 397 | + return 0; | ||
| 398 | + } | ||
| 399 | + return leftXBytes / totalNBytes / base / BUFF_NUM; | ||
| 400 | +} | ||
| 401 | + | ||
| 402 | +int64_t AscendAntiQuantV2Regbase::CalcPerChannelNddmaMaxN(int64_t ubSize, int64_t base) const | ||
| 403 | +{ | ||
| 404 | + int64_t xDtypeSize = ge::GetSizeByDataType(ge::DT_INT8); | ||
| 405 | + int64_t yDtypeSize = ge::GetSizeByDataType(yDtype_); | ||
| 406 | + int64_t scalesDtypeSize = ge::GetSizeByDataType(scaleDtype_); | ||
| 407 | + int64_t offsetDtypeSize = 0; | ||
| 408 | + int64_t totalNBytes = 0; | ||
| 409 | + int64_t leftXBytes = 0; | ||
| 410 | + if (hasOffset_) { | ||
| 411 | + offsetDtypeSize = ge::GetSizeByDataType(scaleDtype_); | ||
| 412 | + } | ||
| 413 | + totalNBytes = base * (xDtypeSize + yDtypeSize + scalesDtypeSize + offsetDtypeSize) * BUFF_NUM; | ||
| 414 | + leftXBytes = ubSize - totalNBytes; | ||
| 415 | + if (leftXBytes <= 0) { | ||
| 416 | + return 1; | ||
| 417 | + } | ||
| 418 | + | ||
| 419 | + return leftXBytes / totalNBytes; | ||
| 420 | +} | ||
| 421 | + | ||
| 422 | +void AscendAntiQuantV2Regbase::CalcPerTensorBlockFactor(int64_t size) | ||
| 423 | +{ | ||
| 424 | + // 以一个cache为基本单位,计算block块的宽度 | ||
| 425 | + blockFactor_ = Ops::Base::CeilDiv(size, actCoreNum_); | ||
| 426 | + int64_t shape = xInputShape_.GetDim(blockAxis_); | ||
| 427 | + int64_t dtypeSize = ge::GetSizeByDataType(ge::DT_INT8); | ||
| 428 | + if (dtypeSize == 0) { | ||
| 429 | + return; | ||
| 430 | + } | ||
| 431 | + blockFactor_ = blockFactor_ * cacheLine_ / dtypeSize; | ||
| 432 | + blockTailFactor_ = shape - blockFactor_ * (actCoreNum_ - 1); | ||
| 433 | + blockTailFactor_ = blockTailFactor_ == 0 ? blockFactor_ : blockTailFactor_; | ||
| 434 | +} | ||
| 435 | + | ||
| 436 | +void AscendAntiQuantV2Regbase::CalcPerChannelBlockFactor(int64_t size) | ||
| 437 | +{ | ||
| 438 | + blockFactor_ = Ops::Base::CeilDiv(size, actCoreNum_); | ||
| 439 | + if (blockAxis_ == 0) { | ||
| 440 | + // 切分合轴的情况,切行数 | ||
| 441 | + blockTailFactor_ = size - blockFactor_ * (actCoreNum_ - 1); | ||
| 442 | + } else { | ||
| 443 | + // 切分尾轴的情况,以一个cache为基本单位 | ||
| 444 | + int64_t shape = xInputShape_.GetDim(blockAxis_); | ||
| 445 | + int64_t dtypeSize = ge::GetSizeByDataType(ge::DT_INT8); | ||
| 446 | + if (dtypeSize != 0) { | ||
| 447 | + blockFactor_ = blockFactor_ * cacheLine_ / dtypeSize; | ||
| 448 | + } else { | ||
| 449 | + blockFactor_ = 0; | ||
| 450 | + } | ||
| 451 | + blockTailFactor_ = shape - blockFactor_ * (actCoreNum_ - 1); | ||
| 452 | + } | ||
| 453 | + blockTailFactor_ = blockTailFactor_ == 0 ? blockFactor_ : blockTailFactor_; | ||
| 454 | +} | ||
| 455 | + | ||
| 456 | +void AscendAntiQuantV2Regbase::CalcPerTensorUBFactor(int64_t numPerCache) | ||
| 457 | +{ | ||
| 458 | + int64_t availableUb = static_cast<int64_t>(ubSize_) - reserveUb_; | ||
| 459 | + int64_t maxBase = CalcMaxBaseLen(availableUb); // 一个UB能算的数 | ||
| 460 | + maxBase = Ops::Base::FloorAlign(maxBase, numPerCache); // 用cacheLine对齐 | ||
| 461 | + int64_t blockBase = blockFactor_; // block块的宽度 | ||
| 462 | + blockBase = Ops::Base::CeilAlign(blockBase, numPerCache); | ||
| 463 | + baseN_ = 1; | ||
| 464 | + baseLen_ = std::min(blockBase, maxBase); | ||
| 465 | +} | ||
| 466 | + | ||
| 467 | +void AscendAntiQuantV2Regbase::CalcPerChannelUBFactor(int64_t numPerCache) | ||
| 468 | +{ | ||
| 469 | + int64_t availableUb = static_cast<int64_t>(ubSize_) - reserveUb_; | ||
| 470 | + int64_t maxBase = CalcMaxBaseLen(availableUb); // 一个UB能算的数 | ||
| 471 | + maxBase = Ops::Base::FloorAlign(maxBase, numPerCache); // 用cacheLine对齐 | ||
| 472 | + // block cut axis 0, means all dim 1 is continous, else each core handle blockFactor | ||
| 473 | + int64_t blockBase = blockAxis_ == 0 ? xInputShape_.GetDim(1) : blockFactor_; // block的宽度,n方向 | ||
| 474 | + blockBase = Ops::Base::CeilAlign(blockBase, numPerCache); // 用cacheLine对齐 | ||
| 475 | + // 至少能放下2行时走第一分支 | ||
| 476 | + if (blockBase <= maxBase / 2) { | ||
| 477 | + // need calc max n with real base | ||
| 478 | + int64_t maxN = CalcMaxN(availableUb, blockBase); // 一个UB能处理几行 | ||
| 479 | + int64_t blockNSize = blockAxis_ == 0 ? blockFactor_ : xInputShape_.GetDim(0); | ||
| 480 | + baseN_ = std::min(maxN, blockNSize); // UB块的行数 | ||
| 481 | + baseLen_ = Ops::Base::CeilAlign(blockBase, numPerCache); // UB块的宽度 | ||
| 482 | + } else { | ||
| 483 | + baseN_ = 1; | ||
| 484 | + baseLen_ = std::min(blockBase, maxBase); | ||
| 485 | + } | ||
| 486 | +} | ||
| 487 | + | ||
| 488 | +void AscendAntiQuantV2Regbase::CalcPerChannelNddmaUBFactor() | ||
| 489 | +{ | ||
| 490 | + // ub can split to three input: x_dtype_size * n * base, x_dtype_size * base, x_dtype_size * base | ||
| 491 | + // and one output: y_dtype_size * n * base | ||
| 492 | + int64_t availableUb = ubSize_ - reserveUb_; | ||
| 493 | + int64_t maxBase = CalcMaxBaseLen(availableUb); // 一个UB能算的数 | ||
| 494 | + int64_t blockBase = blockAxis_ == 0 ? xInputShape_.GetDim(1) : blockFactor_; // block的宽度,n方向 | ||
| 495 | + // 至少能放下2行时走第一分支 | ||
| 496 | + if (blockBase <= maxBase / 2) { | ||
| 497 | + // need calc max n with real base | ||
| 498 | + int64_t maxN = CalcPerChannelNddmaMaxN(availableUb, blockBase); // 一个UB能处理几行 | ||
| 499 | + int64_t blockInnerSize = blockAxis_ == 0 ? blockFactor_ : xInputShape_.GetDim(0); | ||
| 500 | + baseN_ = std::min(maxN, blockInnerSize); // UB块的行数 | ||
| 501 | + baseLen_ = blockBase; // UB块的宽度 | ||
| 502 | + } else { | ||
| 503 | + baseN_ = 1; | ||
| 504 | + baseLen_ = std::min(blockBase, maxBase); | ||
| 505 | + } | ||
| 506 | +} | ||
| 507 | + | ||
| 508 | +void AscendAntiQuantV2Regbase::CalcTiling() | ||
| 509 | +{ | ||
| 510 | + if (mode_ == static_cast<int64_t>(TPL_PER_TENSOR)) { | ||
| 511 | + // per tensor模式,所有轴合一 | ||
| 512 | + int64_t shape = xInputShape_.GetDim(1); | ||
| 513 | + int64_t dtypeSize = ge::GetSizeByDataType(ge::DT_INT8); | ||
| 514 | + if (cacheLine_ == 0 || dtypeSize == 0) { | ||
| 515 | + return; | ||
| 516 | + } | ||
| 517 | + int64_t cacheLineNum = Ops::Base::CeilDiv(shape, cacheLine_ / dtypeSize); | ||
| 518 | + int64_t actCoreNum = | ||
| 519 | + static_cast<int64_t>(GetCoreNum(static_cast<int64_t>(cacheLineNum), static_cast<int64_t>(coreNum_))); | ||
| 520 | + | ||
| 521 | + blockAxis_ = 1; | ||
| 522 | + actCoreNum_ = actCoreNum; | ||
| 523 | + int64_t size = cacheLineNum; | ||
| 524 | + CalcPerTensorBlockFactor(size); | ||
| 525 | + CalcPerTensorUBFactor(cacheLine_ / dtypeSize); | ||
| 526 | + } else if (mode_ == static_cast<int64_t>(TPL_PER_CHANNEL)) { | ||
| 527 | + // per channel模式,1是尾轴,0是其他轴的合轴 | ||
| 528 | + int64_t shape0 = xInputShape_.GetDim(0); | ||
| 529 | + int64_t shape1 = xInputShape_.GetDim(1); | ||
| 530 | + int64_t dtypeSize = ge::GetSizeByDataType(ge::DT_INT8); | ||
| 531 | + if (cacheLine_ == 0 || dtypeSize == 0) { | ||
| 532 | + return; | ||
| 533 | + } | ||
| 534 | + int64_t cacheLineNum = | ||
| 535 | + Ops::Base::CeilDiv(static_cast<int64_t>(shape1), static_cast<int64_t>(cacheLine_ / dtypeSize)); | ||
| 536 | + int64_t actCoreNum0 = static_cast<int64_t>(GetCoreNum(shape0, coreNum_)); | ||
| 537 | + int64_t actCoreNum1 = static_cast<int64_t>(GetCoreNum(cacheLineNum, coreNum_)); | ||
| 538 | + | ||
| 539 | + blockAxis_ = actCoreNum0 >= actCoreNum1 ? 0 : 1; | ||
| 540 | + actCoreNum_ = actCoreNum0 >= actCoreNum1 ? actCoreNum0 : actCoreNum1; | ||
| 541 | + int64_t size = actCoreNum0 >= actCoreNum1 ? shape0 : cacheLineNum; | ||
| 542 | + CalcPerChannelBlockFactor(size); | ||
| 543 | + if (shape1 < LAST_DIM_NUM && blockAxis_ == 0) { | ||
| 544 | + mode_ = TPL_PER_CHANNEL_NDDMA; | ||
| 545 | + CalcPerChannelNddmaUBFactor(); | ||
| 546 | + } else { | ||
| 547 | + CalcPerChannelUBFactor(cacheLine_ / dtypeSize); | ||
| 548 | + } | ||
| 549 | + } else if (mode_ == static_cast<int64_t>(TPL_PER_HEAD)) { | ||
| 550 | + CalcPerHeadTiling(); | ||
| 551 | + } | ||
| 552 | +} | ||
| 553 | + | ||
| 554 | +void AscendAntiQuantV2Regbase::CalcPerHeadTiling() | ||
| 555 | +{ | ||
| 556 | + int64_t shape0 = xInputShape_.GetDim(g_FirstShapeDim); | ||
| 557 | + int64_t shape1 = xInputShape_.GetDim(g_SecondShapeDim); | ||
| 558 | + int64_t shape2 = xInputShape_.GetDim(g_ThirdShapeDim); | ||
| 559 | + int64_t dtypeSize = ge::GetSizeByDataType(ge::DT_INT8); | ||
| 560 | + OP_CHECK_IF(dtypeSize == 0, OP_LOGE(context_->GetNodeName(), "dtypeSize should not be zero."), return); | ||
| 561 | + | ||
| 562 | + if (cacheLine_ == 0 || dtypeSize == 0) { | ||
| 563 | + return; | ||
| 564 | + } | ||
| 565 | + int64_t cacheLineNum = Ops::Base::CeilDiv(shape2, cacheLine_ / dtypeSize); | ||
| 566 | + // split core in S, N, D | ||
| 567 | + // eg. [20, x, x] 40 | ||
| 568 | + int64_t actCoreNum0 = static_cast<int64_t>(GetCoreNum(shape0, coreNum_)); | ||
| 569 | + int64_t actCoreNum1 = static_cast<int64_t>(GetCoreNumDoubleCut(shape0, shape1, coreNum_)); | ||
| 570 | + int64_t actCoreNum2 = static_cast<int64_t>(GetCoreNumDoubleCut(shape0 * shape1, cacheLineNum, coreNum_)); | ||
| 571 | + | ||
| 572 | + blockAxis_ = 0; | ||
| 573 | + actCoreNum_ = actCoreNum0; | ||
| 574 | + if (actCoreNum1 > actCoreNum_) { | ||
| 575 | + blockAxis_ = 1; | ||
| 576 | + actCoreNum_ = actCoreNum1; | ||
| 577 | + } | ||
| 578 | + if (actCoreNum2 > actCoreNum_ && shape2 > g_BlockSize) { | ||
| 579 | + blockAxis_ = static_cast<int64_t>(g_ThirdShapeDim); | ||
| 580 | + actCoreNum_ = actCoreNum2; | ||
| 581 | + } | ||
| 582 | + | ||
| 583 | + CalcPerHeadBlockFactor(); | ||
| 584 | + if (shape2 < LAST_DIM_NUM && (blockAxis_ == 0 || blockAxis_ == 1)) { | ||
| 585 | + mode_ = TPL_PER_HEAD_NDDMA; | ||
| 586 | + CalcPerHeadNddmaUBFactor(); | ||
| 587 | + } else { | ||
| 588 | + CalcPerHeadUBFactor(cacheLine_ / dtypeSize); | ||
| 589 | + } | ||
| 590 | +} | ||
| 591 | + | ||
| 592 | +void AscendAntiQuantV2Regbase::CalcPerHeadBlockFactor() | ||
| 593 | +{ | ||
| 594 | + int64_t shape0 = xInputShape_.GetDim(g_FirstShapeDim); | ||
| 595 | + int64_t shape1 = xInputShape_.GetDim(g_SecondShapeDim); | ||
| 596 | + int64_t shape2 = xInputShape_.GetDim(g_ThirdShapeDim); | ||
| 597 | + int64_t dtypeSize = ge::GetSizeByDataType(ge::DT_INT8); | ||
| 598 | + if (blockAxis_ == 0) { | ||
| 599 | + blockFactor_ = Ops::Base::CeilDiv(shape0, actCoreNum_); | ||
| 600 | + blockTailFactor_ = shape0 - blockFactor_ * (actCoreNum_ - 1); | ||
| 601 | + } else if (blockAxis_ == 1) { | ||
| 602 | + if (shape0 == 0) { | ||
| 603 | + return; | ||
| 604 | + } | ||
| 605 | + blockUnion_ = actCoreNum_ / shape0; | ||
| 606 | + blockFactor_ = Ops::Base::CeilDiv(shape1, blockUnion_); | ||
| 607 | + blockTailFactor_ = shape1 - blockFactor_ * (blockUnion_ - 1); | ||
| 608 | + } else { | ||
| 609 | + if (cacheLine_ == 0 || dtypeSize == 0) { | ||
| 610 | + return; | ||
| 611 | + } | ||
| 612 | + int64_t cacheLineNum = Ops::Base::CeilDiv(shape2, cacheLine_ / dtypeSize); | ||
| 613 | + if (shape0 == 0 || shape1 == 0) { | ||
| 614 | + return; | ||
| 615 | + } | ||
| 616 | + blockUnion_ = actCoreNum_ / shape0 / shape1; | ||
| 617 | + blockFactor_ = Ops::Base::CeilDiv(cacheLineNum, blockUnion_) * cacheLine_ / dtypeSize; | ||
| 618 | + blockTailFactor_ = shape2 - blockFactor_ * (blockUnion_ - 1); | ||
| 619 | + } | ||
| 620 | + blockTailFactor_ = blockTailFactor_ == 0 ? blockFactor_ : blockTailFactor_; | ||
| 621 | +} | ||
| 622 | + | ||
| 623 | +void AscendAntiQuantV2Regbase::CalcPerHeadNddmaUBFactor() | ||
| 624 | +{ | ||
| 625 | + int64_t shape1 = xInputShape_.GetDim(g_SecondShapeDim); | ||
| 626 | + int64_t shape2 = xInputShape_.GetDim(g_ThirdShapeDim); | ||
| 627 | + | ||
| 628 | + int64_t availableUb = static_cast<int64_t>(ubSize_) - reserveUb_; | ||
| 629 | + int64_t maxBase = CalcMaxBaseLen(availableUb); | ||
| 630 | + | ||
| 631 | + // 圈复杂度重构 | ||
| 632 | + if (blockAxis_ == 0) { | ||
| 633 | + if (shape1 * shape2 <= maxBase) { | ||
| 634 | + baseN_ = shape1; | ||
| 635 | + baseLen_ = shape2; | ||
| 636 | + } else if (shape2 <= maxBase) { | ||
| 637 | + if (shape2 == 0) { | ||
| 638 | + return; | ||
| 639 | + } | ||
| 640 | + baseN_ = maxBase / shape2; // must less than shape1 | ||
| 641 | + baseLen_ = shape2; | ||
| 642 | + } else { | ||
| 643 | + baseN_ = 1; | ||
| 644 | + baseLen_ = maxBase; | ||
| 645 | + } | ||
| 646 | + } else { | ||
| 647 | + if (shape2 <= maxBase) { | ||
| 648 | + if (shape2 == 0) { | ||
| 649 | + return; | ||
| 650 | + } | ||
| 651 | + baseN_ = std::min(blockFactor_, maxBase / shape2); | ||
| 652 | + baseLen_ = shape2; | ||
| 653 | + } else { | ||
| 654 | + baseN_ = 1; | ||
| 655 | + baseLen_ = maxBase; | ||
| 656 | + } | ||
| 657 | + } | ||
| 658 | +} | ||
| 659 | + | ||
| 660 | +void AscendAntiQuantV2Regbase::CalcPerHeadUBFactor(int64_t cacheLineNum) | ||
| 661 | +{ | ||
| 662 | + int64_t shape1 = xInputShape_.GetDim(g_SecondShapeDim); | ||
| 663 | + int64_t shape2 = xInputShape_.GetDim(g_ThirdShapeDim); | ||
| 664 | + shape2 = Ops::Base::CeilAlign(shape2, cacheLineNum); | ||
| 665 | + | ||
| 666 | + int64_t availableUb = static_cast<int64_t>(ubSize_) - reserveUb_; | ||
| 667 | + int64_t maxBase = CalcMaxBaseLen(availableUb); | ||
| 668 | + maxBase = Ops::Base::FloorAlign(maxBase, cacheLineNum); | ||
| 669 | + int64_t blockBase = Ops::Base::CeilAlign(blockFactor_, cacheLineNum); | ||
| 670 | + | ||
| 671 | + // 圈复杂度重构 | ||
| 672 | + if (blockAxis_ == 0) { | ||
| 673 | + if (shape1 * shape2 <= maxBase) { | ||
| 674 | + baseN_ = shape1; | ||
| 675 | + baseLen_ = shape2; | ||
| 676 | + } else if (shape2 <= maxBase) { | ||
| 677 | + if (shape2 == 0) { | ||
| 678 | + return; | ||
| 679 | + } | ||
| 680 | + baseN_ = maxBase / shape2; // must less than shape1 | ||
| 681 | + baseLen_ = shape2; | ||
| 682 | + } else { | ||
| 683 | + baseN_ = 1; | ||
| 684 | + baseLen_ = maxBase; | ||
| 685 | + } | ||
| 686 | + } else if (blockAxis_ == 1) { | ||
| 687 | + if (shape2 <= maxBase) { | ||
| 688 | + if (shape2 == 0) { | ||
| 689 | + return; | ||
| 690 | + } | ||
| 691 | + baseN_ = std::min(blockFactor_, maxBase / shape2); | ||
| 692 | + baseLen_ = shape2; | ||
| 693 | + } else { | ||
| 694 | + baseN_ = 1; | ||
| 695 | + baseLen_ = maxBase; | ||
| 696 | + } | ||
| 697 | + } else { | ||
| 698 | + baseN_ = 1; | ||
| 699 | + baseLen_ = std::min(blockBase, maxBase); | ||
| 700 | + } | ||
| 701 | +} | ||
| 702 | + | ||
| 703 | +uint32_t AscendAntiQuantV2Regbase::GetCoreNumDoubleCut(int64_t shape0, int64_t shape1, int64_t coreNum) const | ||
| 704 | +{ | ||
| 705 | + if (shape0 == 0) { | ||
| 706 | + return 0; | ||
| 707 | + } | ||
| 708 | + int64_t yCoreNum = coreNum / shape0; | ||
| 709 | + if (yCoreNum == 0) { | ||
| 710 | + return static_cast<uint32_t>(yCoreNum); | ||
| 711 | + } | ||
| 712 | + uint32_t actCoreNum = GetCoreNum(shape1, yCoreNum); | ||
| 713 | + return static_cast<uint32_t>(shape0 * static_cast<int64_t>(actCoreNum)); | ||
| 714 | +} | ||
| 715 | + | ||
| 716 | +void AscendAntiQuantV2Regbase::CalcTilingKey() | ||
| 717 | +{ | ||
| 718 | + uint32_t zeroPointType = hasOffset_ ? static_cast<uint32_t>(TPL_HAS_OFFSET) : static_cast<uint32_t>(TPL_NO_OFFSET); | ||
| 719 | + uint32_t sqrtModeKey = static_cast<uint32_t>(sqrtMode_); | ||
| 720 | + tilingKey_ = GET_TPL_TILING_KEY(mode_, zeroPointType, sqrtModeKey); | ||
| 721 | +} | ||
| 722 | + | ||
| 723 | +ge::graphStatus AscendAntiQuantV2Regbase::WriteTilingData() | ||
| 724 | +{ | ||
| 725 | + OP_LOGD(context_->GetNodeName(), "coreNum:%ld, tilingKey:%lu", coreNum_, tilingKey_); | ||
| 726 | + context_->SetBlockDim(coreNum_); | ||
| 727 | + context_->SetTilingKey(tilingKey_); | ||
| 728 | + | ||
| 729 | + OP_LOGD(context_->GetNodeName(), "hasOffset:%d, sqrtMode:%d, dstType:%d", hasOffset_, sqrtMode_, dstType_); | ||
| 730 | + | ||
| 731 | + OP_LOGD( | ||
| 732 | + context_->GetNodeName(), | ||
| 733 | + "actCoreNum:%ld, blockAxis:%d, blockFactor:%ld, blockTailFactor:%ld, baseN:%ld, baseLen:%ld", | ||
| 734 | + actCoreNum_, blockAxis_, blockFactor_, blockTailFactor_, baseN_, baseLen_); | ||
| 735 | + | ||
| 736 | + int64_t shape0 = xInputShape_.GetDim(g_FirstShapeDim); | ||
| 737 | + int64_t shape1 = xInputShape_.GetDim(g_SecondShapeDim); | ||
| 738 | + int64_t shape2 = xInputShape_.GetDim(g_ThirdShapeDim); | ||
| 739 | + | ||
| 740 | + tilingData.numCore = actCoreNum_; | ||
| 741 | + tilingData.blockAxis = blockAxis_; | ||
| 742 | + tilingData.blockUnion = blockUnion_; | ||
| 743 | + tilingData.dim0 = shape0; | ||
| 744 | + tilingData.dim1 = shape1; | ||
| 745 | + tilingData.dim2 = shape2; | ||
| 746 | + tilingData.blockFactor = blockFactor_; | ||
| 747 | + tilingData.blockTailFactor = blockTailFactor_; | ||
| 748 | + tilingData.baseN = baseN_; | ||
| 749 | + tilingData.baseLen = baseLen_; | ||
| 750 | + tilingData.hasOffset = hasOffset_; | ||
| 751 | + tilingData.sqrtMode = sqrtMode_; | ||
| 752 | + | ||
| 753 | + uint64_t tilingDataSize = sizeof(tilingData); | ||
| 754 | + errno_t ret = memcpy_s(context_->GetRawTilingData()->GetData(), context_->GetRawTilingData()->GetCapacity(), | ||
| 755 | + reinterpret_cast<void *>(&tilingData), tilingDataSize); | ||
| 756 | + if (ret != EOK) { | ||
| 757 | + OP_LOGD(context_->GetNodeName(), "memcpy_s failde, ret=%d", ret); | ||
| 758 | + return ge::GRAPH_FAILED; | ||
| 759 | + } | ||
| 760 | + context_->GetRawTilingData()->SetDataSize(tilingDataSize); | ||
| 761 | + size_t* currentWorkspace = context_->GetWorkspaceSizes(1); | ||
| 762 | + currentWorkspace[0] = SYNC_WORKSPACE_SIZE; | ||
| 763 | + | ||
| 764 | + return ge::GRAPH_SUCCESS; | ||
| 765 | +} | ||
| 766 | + | ||
| 767 | +static ge::graphStatus TilingForAscendAntiQuantV2(gert::TilingContext* context) | ||
| 768 | +{ | ||
| 769 | + OP_LOGD("AscendAntiQuantV2Tiling", "Enter TilingForAscendAntiQuantV2Tiling"); | ||
| 770 | + | ||
| 771 | + OP_CHECK_IF( | ||
| 772 | + context == nullptr, OP_LOGE("AscendAntiQuantV2Tiling", "Tiling context is null."), | ||
| 773 | + return ge::GRAPH_FAILED); | ||
| 774 | + | ||
| 775 | + AscendAntiQuantV2Regbase AscendAntiQuantV2Tiling(context); | ||
| 776 | + return AscendAntiQuantV2Tiling.DoAscendAntiQuantV2Tiling(); | ||
| 777 | +} | ||
| 778 | + | ||
| 779 | +static ge::graphStatus TilingPrepareForAscendAntiQuantV2(gert::TilingParseContext* context) | ||
| 780 | +{ | ||
| 781 | + OP_LOGD("AscendAntiQuantV2Tiling", "Enter TilingPrepareForAscendAntiQuantV2Tiling"); | ||
| 782 | + | ||
| 783 | + OP_CHECK_IF( | ||
| 784 | + context == nullptr, OP_LOGE("AscendAntiQuantV2Tiling", "TilingParse context is null."), | ||
| 785 | + return ge::GRAPH_FAILED); | ||
| 786 | + | ||
| 787 | + auto compileInfo = context->GetCompiledInfo<AscendAntiQuantV2CompileInfo>(); | ||
| 788 | + OP_CHECK_NULL_WITH_CONTEXT(context, compileInfo); | ||
| 789 | + auto platformInfo = context->GetPlatformInfo(); | ||
| 790 | + OP_CHECK_NULL_WITH_CONTEXT(context, platformInfo); | ||
| 791 | + auto ascendcPlatform = platform_ascendc::PlatformAscendC(platformInfo); | ||
| 792 | + compileInfo->vectorCoreNum = ascendcPlatform.GetCoreNumAiv(); | ||
| 793 | + ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::UB, compileInfo->ubSize); | ||
| 794 | + | ||
| 795 | + OP_CHECK_IF( | ||
| 796 | + (compileInfo->vectorCoreNum <= 0 || compileInfo->ubSize <= 0), | ||
| 797 | + OP_LOGE( | ||
| 798 | + context->GetNodeName(), "AscendAntiQuantV2 GetHardwareInfo Failed, vectorCoreNum:%d, ubSize:%lu.", | ||
| 799 | + compileInfo->vectorCoreNum, compileInfo->ubSize), | ||
| 800 | + return ge::GRAPH_FAILED); | ||
| 801 | + OP_LOGD(context->GetNodeName(), "GetCoreNum:%d, ubSize:%lu", compileInfo->vectorCoreNum, compileInfo->ubSize); | ||
| 802 | + | ||
| 803 | + return ge::GRAPH_SUCCESS; | ||
| 804 | +} | ||
| 805 | + | ||
| 806 | +IMPL_OP_OPTILING(AscendAntiQuantV2) | ||
| 807 | + .Tiling(TilingForAscendAntiQuantV2) | ||
| 808 | + .TilingParse<AscendAntiQuantV2CompileInfo>(TilingPrepareForAscendAntiQuantV2); | ||
| 809 | + | ||
| 810 | +} // namespace optiling | ||
| @@ -0,0 +1,106 @@ | |||
| 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 ascend_anti_quant_v2_regbase_tiling.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + | ||
| 32 | +using namespace Ops::NN::Optiling; | ||
| 33 | + | ||
| 34 | +namespace optiling { | ||
| 35 | +struct AscendAntiQuantV2CompileInfo { | ||
| 36 | + int32_t vectorCoreNum = 0; | ||
| 37 | + uint64_t ubSize = 0; | ||
| 38 | +}; | ||
| 39 | + | ||
| 40 | +class AscendAntiQuantV2Regbase { | ||
| 41 | +public: | ||
| 42 | + explicit AscendAntiQuantV2Regbase(gert::TilingContext* context) : context_(context){}; | ||
| 43 | + ge::graphStatus DoAscendAntiQuantV2Tiling(); | ||
| 44 | + | ||
| 45 | +protected: | ||
| 46 | + ge::graphStatus GetCompileInfo(); | ||
| 47 | + ge::graphStatus GetOpParam(); | ||
| 48 | + ge::graphStatus CheckInputValid( | ||
| 49 | + const gert::Shape& input1, const gert::Shape& input2, const std::string& param) const; | ||
| 50 | + ge::graphStatus CheckOutputValid(const gert::Shape& input, const gert::Shape& output) const; | ||
| 51 | + ge::graphStatus CheckAttrs(const gert::Shape& xShape); | ||
| 52 | + ge::graphStatus WriteTilingData(); | ||
| 53 | + void MergeInputShape(const gert::Shape& input); | ||
| 54 | + uint32_t GetCoreNum(int64_t factor, int64_t coreNum) const; | ||
| 55 | + uint32_t GetCoreNumDoubleCut(int64_t shape0, int64_t shape1, int64_t coreNum) const; | ||
| 56 | + void CalcTiling(); | ||
| 57 | + void CalcTilingKey(); | ||
| 58 | + void CalcPerHeadTiling(); | ||
| 59 | + int64_t CalcMaxBaseLen(int64_t ubSize) const; | ||
| 60 | + int64_t CalcMaxN(int64_t ubSize, int64_t base) const; | ||
| 61 | + int64_t CalcPerChannelNddmaMaxN(int64_t ubSize, int64_t base) const; | ||
| 62 | + void CalcPerTensorBlockFactor(int64_t size); | ||
| 63 | + void CalcPerChannelBlockFactor(int64_t size); | ||
| 64 | + void CalcPerTensorUBFactor(int64_t numPerCache); | ||
| 65 | + void CalcPerChannelUBFactor(int64_t numPerCache); | ||
| 66 | + void CalcPerChannelNddmaUBFactor(); | ||
| 67 | + void CalcPerHeadBlockFactor(); | ||
| 68 | + void CalcPerHeadUBFactor(int64_t cacheLineNum); | ||
| 69 | + void CalcPerHeadNddmaUBFactor(); | ||
| 70 | + | ||
| 71 | + ge::graphStatus CheckShapeEqual(const gert::Shape& shape1, const gert::Shape& shape2) const; | ||
| 72 | + ge::graphStatus CheckInputDtype(); | ||
| 73 | + const gert::Shape& EnsureXAndScaleNotScalar(const gert::Shape& inShape); | ||
| 74 | + const gert::Shape& EnsureYNotScalar(const gert::Shape& inShape); | ||
| 75 | + | ||
| 76 | +private: | ||
| 77 | + gert::TilingContext* context_ = nullptr; | ||
| 78 | + AscendAntiQuantV2TilingData tilingData; | ||
| 79 | + | ||
| 80 | + int64_t coreNum_{0}; | ||
| 81 | + uint64_t ubSize_{0}; | ||
| 82 | + bool isAscend910B_{false}; | ||
| 83 | + int64_t reserveUb_{2048}; | ||
| 84 | + int64_t cacheLine_{256}; | ||
| 85 | + | ||
| 86 | + gert::Shape xInputShape_; | ||
| 87 | + ge::DataType xDtype_{ge::DT_UNDEFINED}; | ||
| 88 | + ge::DataType yDtype_{ge::DT_UNDEFINED}; | ||
| 89 | + ge::DataType scaleDtype_{ge::DT_UNDEFINED}; | ||
| 90 | + bool hasOffset_{true}; | ||
| 91 | + bool useDoubleCut{false}; | ||
| 92 | + int16_t sqrtMode_ = 0; | ||
| 93 | + int32_t dstType_ = 0; | ||
| 94 | + | ||
| 95 | + int64_t actCoreNum_{0}; | ||
| 96 | + int64_t blockUnion_{1}; | ||
| 97 | + int32_t blockAxis_{-1}; | ||
| 98 | + int64_t blockFactor_{-1}; | ||
| 99 | + int64_t blockTailFactor_{-1}; | ||
| 100 | + int64_t baseN_{1}; | ||
| 101 | + int64_t baseLen_{1}; | ||
| 102 | + uint64_t tilingKey_{0}; | ||
| 103 | + uint32_t mode_ = 0; | ||
| 104 | +}; | ||
| 105 | +} // namespace optiling | ||
| 106 | + | ||
| @@ -0,0 +1,1769 @@ | |||
| 1 | +{ | ||
| 2 | + "op_type": "AscendAntiQuantV2", | ||
| 3 | + "op_list": [ | ||
| 4 | + { | ||
| 5 | + "bin_filename": "AscendAntiQuantV2_ffbf03b2f6cdbd5ae89f6191b81f54c2", | ||
| 6 | + "inputs": [ | ||
| 7 | + { | ||
| 8 | + "name": "x", | ||
| 9 | + "index": 0, | ||
| 10 | + "dtype": "int4", | ||
| 11 | + "format": "ND", | ||
| 12 | + "paramType": "required", | ||
| 13 | + "shape": [ | ||
| 14 | + -2 | ||
| 15 | + ], | ||
| 16 | + "format_match_mode": "FormatDefault" | ||
| 17 | + }, | ||
| 18 | + { | ||
| 19 | + "name": "scale", | ||
| 20 | + "index": 1, | ||
| 21 | + "dtype": "bfloat16", | ||
| 22 | + "format": "ND", | ||
| 23 | + "paramType": "required", | ||
| 24 | + "shape": [ | ||
| 25 | + -2 | ||
| 26 | + ], | ||
| 27 | + "format_match_mode": "FormatDefault" | ||
| 28 | + }, | ||
| 29 | + { | ||
| 30 | + "name": "offset", | ||
| 31 | + "index": 2, | ||
| 32 | + "dtype": "bfloat16", | ||
| 33 | + "format": "ND", | ||
| 34 | + "paramType": "optional", | ||
| 35 | + "shape": [ | ||
| 36 | + -2 | ||
| 37 | + ], | ||
| 38 | + "format_match_mode": "FormatDefault" | ||
| 39 | + } | ||
| 40 | + ], | ||
| 41 | + "outputs": [ | ||
| 42 | + { | ||
| 43 | + "name": "y", | ||
| 44 | + "index": 0, | ||
| 45 | + "dtype": "bfloat16", | ||
| 46 | + "format": "ND", | ||
| 47 | + "paramType": "required", | ||
| 48 | + "shape": [ | ||
| 49 | + -2 | ||
| 50 | + ], | ||
| 51 | + "format_match_mode": "FormatDefault" | ||
| 52 | + } | ||
| 53 | + ], | ||
| 54 | + "attrs": [ | ||
| 55 | + { | ||
| 56 | + "name": "dst_type", | ||
| 57 | + "dtype": "int", | ||
| 58 | + "value": null | ||
| 59 | + }, | ||
| 60 | + { | ||
| 61 | + "name": "sqrt_mode", | ||
| 62 | + "dtype": "bool", | ||
| 63 | + "value": false | ||
| 64 | + } | ||
| 65 | + ] | ||
| 66 | + }, | ||
| 67 | + { | ||
| 68 | + "bin_filename": "AscendAntiQuantV2_e0c120dcb633297543605f0ea4d17615", | ||
| 69 | + "inputs": [ | ||
| 70 | + { | ||
| 71 | + "name": "x", | ||
| 72 | + "index": 0, | ||
| 73 | + "dtype": "int4", | ||
| 74 | + "format": "ND", | ||
| 75 | + "paramType": "required", | ||
| 76 | + "shape": [ | ||
| 77 | + -2 | ||
| 78 | + ], | ||
| 79 | + "format_match_mode": "FormatDefault" | ||
| 80 | + }, | ||
| 81 | + { | ||
| 82 | + "name": "scale", | ||
| 83 | + "index": 1, | ||
| 84 | + "dtype": "bfloat16", | ||
| 85 | + "format": "ND", | ||
| 86 | + "paramType": "required", | ||
| 87 | + "shape": [ | ||
| 88 | + -2 | ||
| 89 | + ], | ||
| 90 | + "format_match_mode": "FormatDefault" | ||
| 91 | + }, | ||
| 92 | + { | ||
| 93 | + "name": "offset", | ||
| 94 | + "index": 2, | ||
| 95 | + "dtype": "bfloat16", | ||
| 96 | + "format": "ND", | ||
| 97 | + "paramType": "optional", | ||
| 98 | + "shape": [ | ||
| 99 | + -2 | ||
| 100 | + ], | ||
| 101 | + "format_match_mode": "FormatDefault" | ||
| 102 | + } | ||
| 103 | + ], | ||
| 104 | + "outputs": [ | ||
| 105 | + { | ||
| 106 | + "name": "y", | ||
| 107 | + "index": 0, | ||
| 108 | + "dtype": "bfloat16", | ||
| 109 | + "format": "ND", | ||
| 110 | + "paramType": "required", | ||
| 111 | + "shape": [ | ||
| 112 | + -2 | ||
| 113 | + ], | ||
| 114 | + "format_match_mode": "FormatDefault" | ||
| 115 | + } | ||
| 116 | + ], | ||
| 117 | + "attrs": [ | ||
| 118 | + { | ||
| 119 | + "name": "dst_type", | ||
| 120 | + "dtype": "int", | ||
| 121 | + "value": null | ||
| 122 | + }, | ||
| 123 | + { | ||
| 124 | + "name": "sqrt_mode", | ||
| 125 | + "dtype": "bool", | ||
| 126 | + "value": true | ||
| 127 | + } | ||
| 128 | + ] | ||
| 129 | + }, | ||
| 130 | + { | ||
| 131 | + "bin_filename": "AscendAntiQuantV2_a6f109304ef7c4fca371ecb5a3772011", | ||
| 132 | + "inputs": [ | ||
| 133 | + { | ||
| 134 | + "name": "x", | ||
| 135 | + "index": 0, | ||
| 136 | + "dtype": "int4", | ||
| 137 | + "format": "ND", | ||
| 138 | + "paramType": "required", | ||
| 139 | + "shape": [ | ||
| 140 | + -2 | ||
| 141 | + ], | ||
| 142 | + "format_match_mode": "FormatDefault" | ||
| 143 | + }, | ||
| 144 | + { | ||
| 145 | + "name": "scale", | ||
| 146 | + "index": 1, | ||
| 147 | + "dtype": "bfloat16", | ||
| 148 | + "format": "ND", | ||
| 149 | + "paramType": "required", | ||
| 150 | + "shape": [ | ||
| 151 | + -2 | ||
| 152 | + ], | ||
| 153 | + "format_match_mode": "FormatDefault" | ||
| 154 | + }, | ||
| 155 | + { | ||
| 156 | + "name": "offset", | ||
| 157 | + "index": 2, | ||
| 158 | + "dtype": "bfloat16", | ||
| 159 | + "format": "ND", | ||
| 160 | + "paramType": "optional", | ||
| 161 | + "shape": [ | ||
| 162 | + -2 | ||
| 163 | + ], | ||
| 164 | + "format_match_mode": "FormatDefault" | ||
| 165 | + } | ||
| 166 | + ], | ||
| 167 | + "outputs": [ | ||
| 168 | + { | ||
| 169 | + "name": "y", | ||
| 170 | + "index": 0, | ||
| 171 | + "dtype": "float16", | ||
| 172 | + "format": "ND", | ||
| 173 | + "paramType": "required", | ||
| 174 | + "shape": [ | ||
| 175 | + -2 | ||
| 176 | + ], | ||
| 177 | + "format_match_mode": "FormatDefault" | ||
| 178 | + } | ||
| 179 | + ], | ||
| 180 | + "attrs": [ | ||
| 181 | + { | ||
| 182 | + "name": "dst_type", | ||
| 183 | + "dtype": "int", | ||
| 184 | + "value": null | ||
| 185 | + }, | ||
| 186 | + { | ||
| 187 | + "name": "sqrt_mode", | ||
| 188 | + "dtype": "bool", | ||
| 189 | + "value": false | ||
| 190 | + } | ||
| 191 | + ] | ||
| 192 | + }, | ||
| 193 | + { | ||
| 194 | + "bin_filename": "AscendAntiQuantV2_e14378ddb1b26ab56cbb7da89efe1afb", | ||
| 195 | + "inputs": [ | ||
| 196 | + { | ||
| 197 | + "name": "x", | ||
| 198 | + "index": 0, | ||
| 199 | + "dtype": "int4", | ||
| 200 | + "format": "ND", | ||
| 201 | + "paramType": "required", | ||
| 202 | + "shape": [ | ||
| 203 | + -2 | ||
| 204 | + ], | ||
| 205 | + "format_match_mode": "FormatDefault" | ||
| 206 | + }, | ||
| 207 | + { | ||
| 208 | + "name": "scale", | ||
| 209 | + "index": 1, | ||
| 210 | + "dtype": "bfloat16", | ||
| 211 | + "format": "ND", | ||
| 212 | + "paramType": "required", | ||
| 213 | + "shape": [ | ||
| 214 | + -2 | ||
| 215 | + ], | ||
| 216 | + "format_match_mode": "FormatDefault" | ||
| 217 | + }, | ||
| 218 | + { | ||
| 219 | + "name": "offset", | ||
| 220 | + "index": 2, | ||
| 221 | + "dtype": "bfloat16", | ||
| 222 | + "format": "ND", | ||
| 223 | + "paramType": "optional", | ||
| 224 | + "shape": [ | ||
| 225 | + -2 | ||
| 226 | + ], | ||
| 227 | + "format_match_mode": "FormatDefault" | ||
| 228 | + } | ||
| 229 | + ], | ||
| 230 | + "outputs": [ | ||
| 231 | + { | ||
| 232 | + "name": "y", | ||
| 233 | + "index": 0, | ||
| 234 | + "dtype": "float16", | ||
| 235 | + "format": "ND", | ||
| 236 | + "paramType": "required", | ||
| 237 | + "shape": [ | ||
| 238 | + -2 | ||
| 239 | + ], | ||
| 240 | + "format_match_mode": "FormatDefault" | ||
| 241 | + } | ||
| 242 | + ], | ||
| 243 | + "attrs": [ | ||
| 244 | + { | ||
| 245 | + "name": "dst_type", | ||
| 246 | + "dtype": "int", | ||
| 247 | + "value": null | ||
| 248 | + }, | ||
| 249 | + { | ||
| 250 | + "name": "sqrt_mode", | ||
| 251 | + "dtype": "bool", | ||
| 252 | + "value": true | ||
| 253 | + } | ||
| 254 | + ] | ||
| 255 | + }, | ||
| 256 | + { | ||
| 257 | + "bin_filename": "AscendAntiQuantV2_85bd78a7a62d1d35e6f0fb5cf3ebe859", | ||
| 258 | + "inputs": [ | ||
| 259 | + { | ||
| 260 | + "name": "x", | ||
| 261 | + "index": 0, | ||
| 262 | + "dtype": "int4", | ||
| 263 | + "format": "ND", | ||
| 264 | + "paramType": "required", | ||
| 265 | + "shape": [ | ||
| 266 | + -2 | ||
| 267 | + ], | ||
| 268 | + "format_match_mode": "FormatDefault" | ||
| 269 | + }, | ||
| 270 | + { | ||
| 271 | + "name": "scale", | ||
| 272 | + "index": 1, | ||
| 273 | + "dtype": "float32", | ||
| 274 | + "format": "ND", | ||
| 275 | + "paramType": "required", | ||
| 276 | + "shape": [ | ||
| 277 | + -2 | ||
| 278 | + ], | ||
| 279 | + "format_match_mode": "FormatDefault" | ||
| 280 | + }, | ||
| 281 | + { | ||
| 282 | + "name": "offset", | ||
| 283 | + "index": 2, | ||
| 284 | + "dtype": "float32", | ||
| 285 | + "format": "ND", | ||
| 286 | + "paramType": "optional", | ||
| 287 | + "shape": [ | ||
| 288 | + -2 | ||
| 289 | + ], | ||
| 290 | + "format_match_mode": "FormatDefault" | ||
| 291 | + } | ||
| 292 | + ], | ||
| 293 | + "outputs": [ | ||
| 294 | + { | ||
| 295 | + "name": "y", | ||
| 296 | + "index": 0, | ||
| 297 | + "dtype": "bfloat16", | ||
| 298 | + "format": "ND", | ||
| 299 | + "paramType": "required", | ||
| 300 | + "shape": [ | ||
| 301 | + -2 | ||
| 302 | + ], | ||
| 303 | + "format_match_mode": "FormatDefault" | ||
| 304 | + } | ||
| 305 | + ], | ||
| 306 | + "attrs": [ | ||
| 307 | + { | ||
| 308 | + "name": "dst_type", | ||
| 309 | + "dtype": "int", | ||
| 310 | + "value": null | ||
| 311 | + }, | ||
| 312 | + { | ||
| 313 | + "name": "sqrt_mode", | ||
| 314 | + "dtype": "bool", | ||
| 315 | + "value": false | ||
| 316 | + } | ||
| 317 | + ] | ||
| 318 | + }, | ||
| 319 | + { | ||
| 320 | + "bin_filename": "AscendAntiQuantV2_705d8813a0e4fe0d26c7aa3f0b488bbe", | ||
| 321 | + "inputs": [ | ||
| 322 | + { | ||
| 323 | + "name": "x", | ||
| 324 | + "index": 0, | ||
| 325 | + "dtype": "int4", | ||
| 326 | + "format": "ND", | ||
| 327 | + "paramType": "required", | ||
| 328 | + "shape": [ | ||
| 329 | + -2 | ||
| 330 | + ], | ||
| 331 | + "format_match_mode": "FormatDefault" | ||
| 332 | + }, | ||
| 333 | + { | ||
| 334 | + "name": "scale", | ||
| 335 | + "index": 1, | ||
| 336 | + "dtype": "float32", | ||
| 337 | + "format": "ND", | ||
| 338 | + "paramType": "required", | ||
| 339 | + "shape": [ | ||
| 340 | + -2 | ||
| 341 | + ], | ||
| 342 | + "format_match_mode": "FormatDefault" | ||
| 343 | + }, | ||
| 344 | + { | ||
| 345 | + "name": "offset", | ||
| 346 | + "index": 2, | ||
| 347 | + "dtype": "float32", | ||
| 348 | + "format": "ND", | ||
| 349 | + "paramType": "optional", | ||
| 350 | + "shape": [ | ||
| 351 | + -2 | ||
| 352 | + ], | ||
| 353 | + "format_match_mode": "FormatDefault" | ||
| 354 | + } | ||
| 355 | + ], | ||
| 356 | + "outputs": [ | ||
| 357 | + { | ||
| 358 | + "name": "y", | ||
| 359 | + "index": 0, | ||
| 360 | + "dtype": "bfloat16", | ||
| 361 | + "format": "ND", | ||
| 362 | + "paramType": "required", | ||
| 363 | + "shape": [ | ||
| 364 | + -2 | ||
| 365 | + ], | ||
| 366 | + "format_match_mode": "FormatDefault" | ||
| 367 | + } | ||
| 368 | + ], | ||
| 369 | + "attrs": [ | ||
| 370 | + { | ||
| 371 | + "name": "dst_type", | ||
| 372 | + "dtype": "int", | ||
| 373 | + "value": null | ||
| 374 | + }, | ||
| 375 | + { | ||
| 376 | + "name": "sqrt_mode", | ||
| 377 | + "dtype": "bool", | ||
| 378 | + "value": true | ||
| 379 | + } | ||
| 380 | + ] | ||
| 381 | + }, | ||
| 382 | + { | ||
| 383 | + "bin_filename": "AscendAntiQuantV2_eafcd885a9e8164fccf39b53423c3b56", | ||
| 384 | + "inputs": [ | ||
| 385 | + { | ||
| 386 | + "name": "x", | ||
| 387 | + "index": 0, | ||
| 388 | + "dtype": "int4", | ||
| 389 | + "format": "ND", | ||
| 390 | + "paramType": "required", | ||
| 391 | + "shape": [ | ||
| 392 | + -2 | ||
| 393 | + ], | ||
| 394 | + "format_match_mode": "FormatDefault" | ||
| 395 | + }, | ||
| 396 | + { | ||
| 397 | + "name": "scale", | ||
| 398 | + "index": 1, | ||
| 399 | + "dtype": "float32", | ||
| 400 | + "format": "ND", | ||
| 401 | + "paramType": "required", | ||
| 402 | + "shape": [ | ||
| 403 | + -2 | ||
| 404 | + ], | ||
| 405 | + "format_match_mode": "FormatDefault" | ||
| 406 | + }, | ||
| 407 | + { | ||
| 408 | + "name": "offset", | ||
| 409 | + "index": 2, | ||
| 410 | + "dtype": "float32", | ||
| 411 | + "format": "ND", | ||
| 412 | + "paramType": "optional", | ||
| 413 | + "shape": [ | ||
| 414 | + -2 | ||
| 415 | + ], | ||
| 416 | + "format_match_mode": "FormatDefault" | ||
| 417 | + } | ||
| 418 | + ], | ||
| 419 | + "outputs": [ | ||
| 420 | + { | ||
| 421 | + "name": "y", | ||
| 422 | + "index": 0, | ||
| 423 | + "dtype": "float16", | ||
| 424 | + "format": "ND", | ||
| 425 | + "paramType": "required", | ||
| 426 | + "shape": [ | ||
| 427 | + -2 | ||
| 428 | + ], | ||
| 429 | + "format_match_mode": "FormatDefault" | ||
| 430 | + } | ||
| 431 | + ], | ||
| 432 | + "attrs": [ | ||
| 433 | + { | ||
| 434 | + "name": "dst_type", | ||
| 435 | + "dtype": "int", | ||
| 436 | + "value": null | ||
| 437 | + }, | ||
| 438 | + { | ||
| 439 | + "name": "sqrt_mode", | ||
| 440 | + "dtype": "bool", | ||
| 441 | + "value": false | ||
| 442 | + } | ||
| 443 | + ] | ||
| 444 | + }, | ||
| 445 | + { | ||
| 446 | + "bin_filename": "AscendAntiQuantV2_bc5890e36c219f6d89e9500fb83fbe67", | ||
| 447 | + "inputs": [ | ||
| 448 | + { | ||
| 449 | + "name": "x", | ||
| 450 | + "index": 0, | ||
| 451 | + "dtype": "int4", | ||
| 452 | + "format": "ND", | ||
| 453 | + "paramType": "required", | ||
| 454 | + "shape": [ | ||
| 455 | + -2 | ||
| 456 | + ], | ||
| 457 | + "format_match_mode": "FormatDefault" | ||
| 458 | + }, | ||
| 459 | + { | ||
| 460 | + "name": "scale", | ||
| 461 | + "index": 1, | ||
| 462 | + "dtype": "float32", | ||
| 463 | + "format": "ND", | ||
| 464 | + "paramType": "required", | ||
| 465 | + "shape": [ | ||
| 466 | + -2 | ||
| 467 | + ], | ||
| 468 | + "format_match_mode": "FormatDefault" | ||
| 469 | + }, | ||
| 470 | + { | ||
| 471 | + "name": "offset", | ||
| 472 | + "index": 2, | ||
| 473 | + "dtype": "float32", | ||
| 474 | + "format": "ND", | ||
| 475 | + "paramType": "optional", | ||
| 476 | + "shape": [ | ||
| 477 | + -2 | ||
| 478 | + ], | ||
| 479 | + "format_match_mode": "FormatDefault" | ||
| 480 | + } | ||
| 481 | + ], | ||
| 482 | + "outputs": [ | ||
| 483 | + { | ||
| 484 | + "name": "y", | ||
| 485 | + "index": 0, | ||
| 486 | + "dtype": "float16", | ||
| 487 | + "format": "ND", | ||
| 488 | + "paramType": "required", | ||
| 489 | + "shape": [ | ||
| 490 | + -2 | ||
| 491 | + ], | ||
| 492 | + "format_match_mode": "FormatDefault" | ||
| 493 | + } | ||
| 494 | + ], | ||
| 495 | + "attrs": [ | ||
| 496 | + { | ||
| 497 | + "name": "dst_type", | ||
| 498 | + "dtype": "int", | ||
| 499 | + "value": null | ||
| 500 | + }, | ||
| 501 | + { | ||
| 502 | + "name": "sqrt_mode", | ||
| 503 | + "dtype": "bool", | ||
| 504 | + "value": true | ||
| 505 | + } | ||
| 506 | + ] | ||
| 507 | + }, | ||
| 508 | + { | ||
| 509 | + "bin_filename": "AscendAntiQuantV2_6c286918b80d339a2939bf4648e2012f", | ||
| 510 | + "inputs": [ | ||
| 511 | + { | ||
| 512 | + "name": "x", | ||
| 513 | + "index": 0, | ||
| 514 | + "dtype": "int8", | ||
| 515 | + "format": "ND", | ||
| 516 | + "paramType": "required", | ||
| 517 | + "shape": [ | ||
| 518 | + -2 | ||
| 519 | + ], | ||
| 520 | + "format_match_mode": "FormatDefault" | ||
| 521 | + }, | ||
| 522 | + { | ||
| 523 | + "name": "scale", | ||
| 524 | + "index": 1, | ||
| 525 | + "dtype": "bfloat16", | ||
| 526 | + "format": "ND", | ||
| 527 | + "paramType": "required", | ||
| 528 | + "shape": [ | ||
| 529 | + -2 | ||
| 530 | + ], | ||
| 531 | + "format_match_mode": "FormatDefault" | ||
| 532 | + }, | ||
| 533 | + { | ||
| 534 | + "name": "offset", | ||
| 535 | + "index": 2, | ||
| 536 | + "dtype": "bfloat16", | ||
| 537 | + "format": "ND", | ||
| 538 | + "paramType": "optional", | ||
| 539 | + "shape": [ | ||
| 540 | + -2 | ||
| 541 | + ], | ||
| 542 | + "format_match_mode": "FormatDefault" | ||
| 543 | + } | ||
| 544 | + ], | ||
| 545 | + "outputs": [ | ||
| 546 | + { | ||
| 547 | + "name": "y", | ||
| 548 | + "index": 0, | ||
| 549 | + "dtype": "bfloat16", | ||
| 550 | + "format": "ND", | ||
| 551 | + "paramType": "required", | ||
| 552 | + "shape": [ | ||
| 553 | + -2 | ||
| 554 | + ], | ||
| 555 | + "format_match_mode": "FormatDefault" | ||
| 556 | + } | ||
| 557 | + ], | ||
| 558 | + "attrs": [ | ||
| 559 | + { | ||
| 560 | + "name": "dst_type", | ||
| 561 | + "dtype": "int", | ||
| 562 | + "value": null | ||
| 563 | + }, | ||
| 564 | + { | ||
| 565 | + "name": "sqrt_mode", | ||
| 566 | + "dtype": "bool", | ||
| 567 | + "value": false | ||
| 568 | + } | ||
| 569 | + ] | ||
| 570 | + }, | ||
| 571 | + { | ||
| 572 | + "bin_filename": "AscendAntiQuantV2_bb59d06bddcf2044e44305e84ee88d61", | ||
| 573 | + "inputs": [ | ||
| 574 | + { | ||
| 575 | + "name": "x", | ||
| 576 | + "index": 0, | ||
| 577 | + "dtype": "int8", | ||
| 578 | + "format": "ND", | ||
| 579 | + "paramType": "required", | ||
| 580 | + "shape": [ | ||
| 581 | + -2 | ||
| 582 | + ], | ||
| 583 | + "format_match_mode": "FormatDefault" | ||
| 584 | + }, | ||
| 585 | + { | ||
| 586 | + "name": "scale", | ||
| 587 | + "index": 1, | ||
| 588 | + "dtype": "bfloat16", | ||
| 589 | + "format": "ND", | ||
| 590 | + "paramType": "required", | ||
| 591 | + "shape": [ | ||
| 592 | + -2 | ||
| 593 | + ], | ||
| 594 | + "format_match_mode": "FormatDefault" | ||
| 595 | + }, | ||
| 596 | + { | ||
| 597 | + "name": "offset", | ||
| 598 | + "index": 2, | ||
| 599 | + "dtype": "bfloat16", | ||
| 600 | + "format": "ND", | ||
| 601 | + "paramType": "optional", | ||
| 602 | + "shape": [ | ||
| 603 | + -2 | ||
| 604 | + ], | ||
| 605 | + "format_match_mode": "FormatDefault" | ||
| 606 | + } | ||
| 607 | + ], | ||
| 608 | + "outputs": [ | ||
| 609 | + { | ||
| 610 | + "name": "y", | ||
| 611 | + "index": 0, | ||
| 612 | + "dtype": "bfloat16", | ||
| 613 | + "format": "ND", | ||
| 614 | + "paramType": "required", | ||
| 615 | + "shape": [ | ||
| 616 | + -2 | ||
| 617 | + ], | ||
| 618 | + "format_match_mode": "FormatDefault" | ||
| 619 | + } | ||
| 620 | + ], | ||
| 621 | + "attrs": [ | ||
| 622 | + { | ||
| 623 | + "name": "dst_type", | ||
| 624 | + "dtype": "int", | ||
| 625 | + "value": null | ||
| 626 | + }, | ||
| 627 | + { | ||
| 628 | + "name": "sqrt_mode", | ||
| 629 | + "dtype": "bool", | ||
| 630 | + "value": true | ||
| 631 | + } | ||
| 632 | + ] | ||
| 633 | + }, | ||
| 634 | + { | ||
| 635 | + "bin_filename": "AscendAntiQuantV2_d9de980292c01a395ca23266162ed8d7", | ||
| 636 | + "inputs": [ | ||
| 637 | + { | ||
| 638 | + "name": "x", | ||
| 639 | + "index": 0, | ||
| 640 | + "dtype": "int8", | ||
| 641 | + "format": "ND", | ||
| 642 | + "paramType": "required", | ||
| 643 | + "shape": [ | ||
| 644 | + -2 | ||
| 645 | + ], | ||
| 646 | + "format_match_mode": "FormatDefault" | ||
| 647 | + }, | ||
| 648 | + { | ||
| 649 | + "name": "scale", | ||
| 650 | + "index": 1, | ||
| 651 | + "dtype": "bfloat16", | ||
| 652 | + "format": "ND", | ||
| 653 | + "paramType": "required", | ||
| 654 | + "shape": [ | ||
| 655 | + -2 | ||
| 656 | + ], | ||
| 657 | + "format_match_mode": "FormatDefault" | ||
| 658 | + }, | ||
| 659 | + { | ||
| 660 | + "name": "offset", | ||
| 661 | + "index": 2, | ||
| 662 | + "dtype": "bfloat16", | ||
| 663 | + "format": "ND", | ||
| 664 | + "paramType": "optional", | ||
| 665 | + "shape": [ | ||
| 666 | + -2 | ||
| 667 | + ], | ||
| 668 | + "format_match_mode": "FormatDefault" | ||
| 669 | + } | ||
| 670 | + ], | ||
| 671 | + "outputs": [ | ||
| 672 | + { | ||
| 673 | + "name": "y", | ||
| 674 | + "index": 0, | ||
| 675 | + "dtype": "float16", | ||
| 676 | + "format": "ND", | ||
| 677 | + "paramType": "required", | ||
| 678 | + "shape": [ | ||
| 679 | + -2 | ||
| 680 | + ], | ||
| 681 | + "format_match_mode": "FormatDefault" | ||
| 682 | + } | ||
| 683 | + ], | ||
| 684 | + "attrs": [ | ||
| 685 | + { | ||
| 686 | + "name": "dst_type", | ||
| 687 | + "dtype": "int", | ||
| 688 | + "value": null | ||
| 689 | + }, | ||
| 690 | + { | ||
| 691 | + "name": "sqrt_mode", | ||
| 692 | + "dtype": "bool", | ||
| 693 | + "value": false | ||
| 694 | + } | ||
| 695 | + ] | ||
| 696 | + }, | ||
| 697 | + { | ||
| 698 | + "bin_filename": "AscendAntiQuantV2_ef54143ef2f0bc28156ab4ea700ffb00", | ||
| 699 | + "inputs": [ | ||
| 700 | + { | ||
| 701 | + "name": "x", | ||
| 702 | + "index": 0, | ||
| 703 | + "dtype": "int8", | ||
| 704 | + "format": "ND", | ||
| 705 | + "paramType": "required", | ||
| 706 | + "shape": [ | ||
| 707 | + -2 | ||
| 708 | + ], | ||
| 709 | + "format_match_mode": "FormatDefault" | ||
| 710 | + }, | ||
| 711 | + { | ||
| 712 | + "name": "scale", | ||
| 713 | + "index": 1, | ||
| 714 | + "dtype": "bfloat16", | ||
| 715 | + "format": "ND", | ||
| 716 | + "paramType": "required", | ||
| 717 | + "shape": [ | ||
| 718 | + -2 | ||
| 719 | + ], | ||
| 720 | + "format_match_mode": "FormatDefault" | ||
| 721 | + }, | ||
| 722 | + { | ||
| 723 | + "name": "offset", | ||
| 724 | + "index": 2, | ||
| 725 | + "dtype": "bfloat16", | ||
| 726 | + "format": "ND", | ||
| 727 | + "paramType": "optional", | ||
| 728 | + "shape": [ | ||
| 729 | + -2 | ||
| 730 | + ], | ||
| 731 | + "format_match_mode": "FormatDefault" | ||
| 732 | + } | ||
| 733 | + ], | ||
| 734 | + "outputs": [ | ||
| 735 | + { | ||
| 736 | + "name": "y", | ||
| 737 | + "index": 0, | ||
| 738 | + "dtype": "float16", | ||
| 739 | + "format": "ND", | ||
| 740 | + "paramType": "required", | ||
| 741 | + "shape": [ | ||
| 742 | + -2 | ||
| 743 | + ], | ||
| 744 | + "format_match_mode": "FormatDefault" | ||
| 745 | + } | ||
| 746 | + ], | ||
| 747 | + "attrs": [ | ||
| 748 | + { | ||
| 749 | + "name": "dst_type", | ||
| 750 | + "dtype": "int", | ||
| 751 | + "value": null | ||
| 752 | + }, | ||
| 753 | + { | ||
| 754 | + "name": "sqrt_mode", | ||
| 755 | + "dtype": "bool", | ||
| 756 | + "value": true | ||
| 757 | + } | ||
| 758 | + ] | ||
| 759 | + }, | ||
| 760 | + { | ||
| 761 | + "bin_filename": "AscendAntiQuantV2_bd2d9bd1655309893571009244932570", | ||
| 762 | + "inputs": [ | ||
| 763 | + { | ||
| 764 | + "name": "x", | ||
| 765 | + "index": 0, | ||
| 766 | + "dtype": "int8", | ||
| 767 | + "format": "ND", | ||
| 768 | + "paramType": "required", | ||
| 769 | + "shape": [ | ||
| 770 | + -2 | ||
| 771 | + ], | ||
| 772 | + "format_match_mode": "FormatDefault" | ||
| 773 | + }, | ||
| 774 | + { | ||
| 775 | + "name": "scale", | ||
| 776 | + "index": 1, | ||
| 777 | + "dtype": "float32", | ||
| 778 | + "format": "ND", | ||
| 779 | + "paramType": "required", | ||
| 780 | + "shape": [ | ||
| 781 | + -2 | ||
| 782 | + ], | ||
| 783 | + "format_match_mode": "FormatDefault" | ||
| 784 | + }, | ||
| 785 | + { | ||
| 786 | + "name": "offset", | ||
| 787 | + "index": 2, | ||
| 788 | + "dtype": "float32", | ||
| 789 | + "format": "ND", | ||
| 790 | + "paramType": "optional", | ||
| 791 | + "shape": [ | ||
| 792 | + -2 | ||
| 793 | + ], | ||
| 794 | + "format_match_mode": "FormatDefault" | ||
| 795 | + } | ||
| 796 | + ], | ||
| 797 | + "outputs": [ | ||
| 798 | + { | ||
| 799 | + "name": "y", | ||
| 800 | + "index": 0, | ||
| 801 | + "dtype": "bfloat16", | ||
| 802 | + "format": "ND", | ||
| 803 | + "paramType": "required", | ||
| 804 | + "shape": [ | ||
| 805 | + -2 | ||
| 806 | + ], | ||
| 807 | + "format_match_mode": "FormatDefault" | ||
| 808 | + } | ||
| 809 | + ], | ||
| 810 | + "attrs": [ | ||
| 811 | + { | ||
| 812 | + "name": "dst_type", | ||
| 813 | + "dtype": "int", | ||
| 814 | + "value": null | ||
| 815 | + }, | ||
| 816 | + { | ||
| 817 | + "name": "sqrt_mode", | ||
| 818 | + "dtype": "bool", | ||
| 819 | + "value": false | ||
| 820 | + } | ||
| 821 | + ] | ||
| 822 | + }, | ||
| 823 | + { | ||
| 824 | + "bin_filename": "AscendAntiQuantV2_224c105876bb783e521dc1a5debdd6aa", | ||
| 825 | + "inputs": [ | ||
| 826 | + { | ||
| 827 | + "name": "x", | ||
| 828 | + "index": 0, | ||
| 829 | + "dtype": "int8", | ||
| 830 | + "format": "ND", | ||
| 831 | + "paramType": "required", | ||
| 832 | + "shape": [ | ||
| 833 | + -2 | ||
| 834 | + ], | ||
| 835 | + "format_match_mode": "FormatDefault" | ||
| 836 | + }, | ||
| 837 | + { | ||
| 838 | + "name": "scale", | ||
| 839 | + "index": 1, | ||
| 840 | + "dtype": "float32", | ||
| 841 | + "format": "ND", | ||
| 842 | + "paramType": "required", | ||
| 843 | + "shape": [ | ||
| 844 | + -2 | ||
| 845 | + ], | ||
| 846 | + "format_match_mode": "FormatDefault" | ||
| 847 | + }, | ||
| 848 | + { | ||
| 849 | + "name": "offset", | ||
| 850 | + "index": 2, | ||
| 851 | + "dtype": "float32", | ||
| 852 | + "format": "ND", | ||
| 853 | + "paramType": "optional", | ||
| 854 | + "shape": [ | ||
| 855 | + -2 | ||
| 856 | + ], | ||
| 857 | + "format_match_mode": "FormatDefault" | ||
| 858 | + } | ||
| 859 | + ], | ||
| 860 | + "outputs": [ | ||
| 861 | + { | ||
| 862 | + "name": "y", | ||
| 863 | + "index": 0, | ||
| 864 | + "dtype": "bfloat16", | ||
| 865 | + "format": "ND", | ||
| 866 | + "paramType": "required", | ||
| 867 | + "shape": [ | ||
| 868 | + -2 | ||
| 869 | + ], | ||
| 870 | + "format_match_mode": "FormatDefault" | ||
| 871 | + } | ||
| 872 | + ], | ||
| 873 | + "attrs": [ | ||
| 874 | + { | ||
| 875 | + "name": "dst_type", | ||
| 876 | + "dtype": "int", | ||
| 877 | + "value": null | ||
| 878 | + }, | ||
| 879 | + { | ||
| 880 | + "name": "sqrt_mode", | ||
| 881 | + "dtype": "bool", | ||
| 882 | + "value": true | ||
| 883 | + } | ||
| 884 | + ] | ||
| 885 | + }, | ||
| 886 | + { | ||
| 887 | + "bin_filename": "AscendAntiQuantV2_c84bab62aa86157583f9fa95f401c00f", | ||
| 888 | + "inputs": [ | ||
| 889 | + { | ||
| 890 | + "name": "x", | ||
| 891 | + "index": 0, | ||
| 892 | + "dtype": "int8", | ||
| 893 | + "format": "ND", | ||
| 894 | + "paramType": "required", | ||
| 895 | + "shape": [ | ||
| 896 | + -2 | ||
| 897 | + ], | ||
| 898 | + "format_match_mode": "FormatDefault" | ||
| 899 | + }, | ||
| 900 | + { | ||
| 901 | + "name": "scale", | ||
| 902 | + "index": 1, | ||
| 903 | + "dtype": "float32", | ||
| 904 | + "format": "ND", | ||
| 905 | + "paramType": "required", | ||
| 906 | + "shape": [ | ||
| 907 | + -2 | ||
| 908 | + ], | ||
| 909 | + "format_match_mode": "FormatDefault" | ||
| 910 | + }, | ||
| 911 | + { | ||
| 912 | + "name": "offset", | ||
| 913 | + "index": 2, | ||
| 914 | + "dtype": "float32", | ||
| 915 | + "format": "ND", | ||
| 916 | + "paramType": "optional", | ||
| 917 | + "shape": [ | ||
| 918 | + -2 | ||
| 919 | + ], | ||
| 920 | + "format_match_mode": "FormatDefault" | ||
| 921 | + } | ||
| 922 | + ], | ||
| 923 | + "outputs": [ | ||
| 924 | + { | ||
| 925 | + "name": "y", | ||
| 926 | + "index": 0, | ||
| 927 | + "dtype": "float16", | ||
| 928 | + "format": "ND", | ||
| 929 | + "paramType": "required", | ||
| 930 | + "shape": [ | ||
| 931 | + -2 | ||
| 932 | + ], | ||
| 933 | + "format_match_mode": "FormatDefault" | ||
| 934 | + } | ||
| 935 | + ], | ||
| 936 | + "attrs": [ | ||
| 937 | + { | ||
| 938 | + "name": "dst_type", | ||
| 939 | + "dtype": "int", | ||
| 940 | + "value": null | ||
| 941 | + }, | ||
| 942 | + { | ||
| 943 | + "name": "sqrt_mode", | ||
| 944 | + "dtype": "bool", | ||
| 945 | + "value": false | ||
| 946 | + } | ||
| 947 | + ] | ||
| 948 | + }, | ||
| 949 | + { | ||
| 950 | + "bin_filename": "AscendAntiQuantV2_650baea70767c4bd7838a0d2f6aa3472", | ||
| 951 | + "inputs": [ | ||
| 952 | + { | ||
| 953 | + "name": "x", | ||
| 954 | + "index": 0, | ||
| 955 | + "dtype": "int8", | ||
| 956 | + "format": "ND", | ||
| 957 | + "paramType": "required", | ||
| 958 | + "shape": [ | ||
| 959 | + -2 | ||
| 960 | + ], | ||
| 961 | + "format_match_mode": "FormatDefault" | ||
| 962 | + }, | ||
| 963 | + { | ||
| 964 | + "name": "scale", | ||
| 965 | + "index": 1, | ||
| 966 | + "dtype": "float32", | ||
| 967 | + "format": "ND", | ||
| 968 | + "paramType": "required", | ||
| 969 | + "shape": [ | ||
| 970 | + -2 | ||
| 971 | + ], | ||
| 972 | + "format_match_mode": "FormatDefault" | ||
| 973 | + }, | ||
| 974 | + { | ||
| 975 | + "name": "offset", | ||
| 976 | + "index": 2, | ||
| 977 | + "dtype": "float32", | ||
| 978 | + "format": "ND", | ||
| 979 | + "paramType": "optional", | ||
| 980 | + "shape": [ | ||
| 981 | + -2 | ||
| 982 | + ], | ||
| 983 | + "format_match_mode": "FormatDefault" | ||
| 984 | + } | ||
| 985 | + ], | ||
| 986 | + "outputs": [ | ||
| 987 | + { | ||
| 988 | + "name": "y", | ||
| 989 | + "index": 0, | ||
| 990 | + "dtype": "float16", | ||
| 991 | + "format": "ND", | ||
| 992 | + "paramType": "required", | ||
| 993 | + "shape": [ | ||
| 994 | + -2 | ||
| 995 | + ], | ||
| 996 | + "format_match_mode": "FormatDefault" | ||
| 997 | + } | ||
| 998 | + ], | ||
| 999 | + "attrs": [ | ||
| 1000 | + { | ||
| 1001 | + "name": "dst_type", | ||
| 1002 | + "dtype": "int", | ||
| 1003 | + "value": null | ||
| 1004 | + }, | ||
| 1005 | + { | ||
| 1006 | + "name": "sqrt_mode", | ||
| 1007 | + "dtype": "bool", | ||
| 1008 | + "value": true | ||
| 1009 | + } | ||
| 1010 | + ] | ||
| 1011 | + }, | ||
| 1012 | + { | ||
| 1013 | + "bin_filename": "AscendAntiQuantV2_650baea70767c4bd7838a0d2f6aa3432", | ||
| 1014 | + "inputs": [ | ||
| 1015 | + { | ||
| 1016 | + "name": "x", | ||
| 1017 | + "index": 0, | ||
| 1018 | + "dtype": "hifloat8", | ||
| 1019 | + "format": "ND", | ||
| 1020 | + "paramType": "required", | ||
| 1021 | + "shape": [ | ||
| 1022 | + -2 | ||
| 1023 | + ], | ||
| 1024 | + "format_match_mode": "FormatDefault" | ||
| 1025 | + }, | ||
| 1026 | + { | ||
| 1027 | + "name": "scale", | ||
| 1028 | + "index": 1, | ||
| 1029 | + "dtype": "float32", | ||
| 1030 | + "format": "ND", | ||
| 1031 | + "paramType": "required", | ||
| 1032 | + "shape": [ | ||
| 1033 | + -2 | ||
| 1034 | + ], | ||
| 1035 | + "format_match_mode": "FormatDefault" | ||
| 1036 | + }, | ||
| 1037 | + { | ||
| 1038 | + "name": "offset", | ||
| 1039 | + "index": 2, | ||
| 1040 | + "dtype": "float32", | ||
| 1041 | + "format": "ND", | ||
| 1042 | + "paramType": "optional", | ||
| 1043 | + "shape": [ | ||
| 1044 | + -2 | ||
| 1045 | + ], | ||
| 1046 | + "format_match_mode": "FormatDefault" | ||
| 1047 | + } | ||
| 1048 | + ], | ||
| 1049 | + "outputs": [ | ||
| 1050 | + { | ||
| 1051 | + "name": "y", | ||
| 1052 | + "index": 0, | ||
| 1053 | + "dtype": "float16", | ||
| 1054 | + "format": "ND", | ||
| 1055 | + "paramType": "required", | ||
| 1056 | + "shape": [ | ||
| 1057 | + -2 | ||
| 1058 | + ], | ||
| 1059 | + "format_match_mode": "FormatDefault" | ||
| 1060 | + } | ||
| 1061 | + ], | ||
| 1062 | + "attrs": [ | ||
| 1063 | + { | ||
| 1064 | + "name": "dst_type", | ||
| 1065 | + "dtype": "int", | ||
| 1066 | + "value": null | ||
| 1067 | + }, | ||
| 1068 | + { | ||
| 1069 | + "name": "sqrt_mode", | ||
| 1070 | + "dtype": "bool", | ||
| 1071 | + "value": false | ||
| 1072 | + } | ||
| 1073 | + ] | ||
| 1074 | + }, | ||
| 1075 | + { | ||
| 1076 | + "bin_filename": "AscendAntiQuantV2_650baea70767c4bd7838a0d2f6aa7389", | ||
| 1077 | + "inputs": [ | ||
| 1078 | + { | ||
| 1079 | + "name": "x", | ||
| 1080 | + "index": 0, | ||
| 1081 | + "dtype": "hifloat8", | ||
| 1082 | + "format": "ND", | ||
| 1083 | + "paramType": "required", | ||
| 1084 | + "shape": [ | ||
| 1085 | + -2 | ||
| 1086 | + ], | ||
| 1087 | + "format_match_mode": "FormatDefault" | ||
| 1088 | + }, | ||
| 1089 | + { | ||
| 1090 | + "name": "scale", | ||
| 1091 | + "index": 1, | ||
| 1092 | + "dtype": "float32", | ||
| 1093 | + "format": "ND", | ||
| 1094 | + "paramType": "required", | ||
| 1095 | + "shape": [ | ||
| 1096 | + -2 | ||
| 1097 | + ], | ||
| 1098 | + "format_match_mode": "FormatDefault" | ||
| 1099 | + }, | ||
| 1100 | + { | ||
| 1101 | + "name": "offset", | ||
| 1102 | + "index": 2, | ||
| 1103 | + "dtype": "float32", | ||
| 1104 | + "format": "ND", | ||
| 1105 | + "paramType": "optional", | ||
| 1106 | + "shape": [ | ||
| 1107 | + -2 | ||
| 1108 | + ], | ||
| 1109 | + "format_match_mode": "FormatDefault" | ||
| 1110 | + } | ||
| 1111 | + ], | ||
| 1112 | + "outputs": [ | ||
| 1113 | + { | ||
| 1114 | + "name": "y", | ||
| 1115 | + "index": 0, | ||
| 1116 | + "dtype": "float16", | ||
| 1117 | + "format": "ND", | ||
| 1118 | + "paramType": "required", | ||
| 1119 | + "shape": [ | ||
| 1120 | + -2 | ||
| 1121 | + ], | ||
| 1122 | + "format_match_mode": "FormatDefault" | ||
| 1123 | + } | ||
| 1124 | + ], | ||
| 1125 | + "attrs": [ | ||
| 1126 | + { | ||
| 1127 | + "name": "dst_type", | ||
| 1128 | + "dtype": "int", | ||
| 1129 | + "value": null | ||
| 1130 | + }, | ||
| 1131 | + { | ||
| 1132 | + "name": "sqrt_mode", | ||
| 1133 | + "dtype": "bool", | ||
| 1134 | + "value": true | ||
| 1135 | + } | ||
| 1136 | + ] | ||
| 1137 | + }, | ||
| 1138 | + { | ||
| 1139 | + "bin_filename": "AscendAntiQuantV2_650baea70767c4bd7838a0d2f6aa9921", | ||
| 1140 | + "inputs": [ | ||
| 1141 | + { | ||
| 1142 | + "name": "x", | ||
| 1143 | + "index": 0, | ||
| 1144 | + "dtype": "hifloat8", | ||
| 1145 | + "format": "ND", | ||
| 1146 | + "paramType": "required", | ||
| 1147 | + "shape": [ | ||
| 1148 | + -2 | ||
| 1149 | + ], | ||
| 1150 | + "format_match_mode": "FormatDefault" | ||
| 1151 | + }, | ||
| 1152 | + { | ||
| 1153 | + "name": "scale", | ||
| 1154 | + "index": 1, | ||
| 1155 | + "dtype": "float32", | ||
| 1156 | + "format": "ND", | ||
| 1157 | + "paramType": "required", | ||
| 1158 | + "shape": [ | ||
| 1159 | + -2 | ||
| 1160 | + ], | ||
| 1161 | + "format_match_mode": "FormatDefault" | ||
| 1162 | + }, | ||
| 1163 | + { | ||
| 1164 | + "name": "offset", | ||
| 1165 | + "index": 2, | ||
| 1166 | + "dtype": "float32", | ||
| 1167 | + "format": "ND", | ||
| 1168 | + "paramType": "optional", | ||
| 1169 | + "shape": [ | ||
| 1170 | + -2 | ||
| 1171 | + ], | ||
| 1172 | + "format_match_mode": "FormatDefault" | ||
| 1173 | + } | ||
| 1174 | + ], | ||
| 1175 | + "outputs": [ | ||
| 1176 | + { | ||
| 1177 | + "name": "y", | ||
| 1178 | + "index": 0, | ||
| 1179 | + "dtype": "bfloat16", | ||
| 1180 | + "format": "ND", | ||
| 1181 | + "paramType": "required", | ||
| 1182 | + "shape": [ | ||
| 1183 | + -2 | ||
| 1184 | + ], | ||
| 1185 | + "format_match_mode": "FormatDefault" | ||
| 1186 | + } | ||
| 1187 | + ], | ||
| 1188 | + "attrs": [ | ||
| 1189 | + { | ||
| 1190 | + "name": "dst_type", | ||
| 1191 | + "dtype": "int", | ||
| 1192 | + "value": null | ||
| 1193 | + }, | ||
| 1194 | + { | ||
| 1195 | + "name": "sqrt_mode", | ||
| 1196 | + "dtype": "bool", | ||
| 1197 | + "value": false | ||
| 1198 | + } | ||
| 1199 | + ] | ||
| 1200 | + }, | ||
| 1201 | + { | ||
| 1202 | + "bin_filename": "AscendAntiQuantV2_650baea70767c4bd7838a0d2f6aa8821", | ||
| 1203 | + "inputs": [ | ||
| 1204 | + { | ||
| 1205 | + "name": "x", | ||
| 1206 | + "index": 0, | ||
| 1207 | + "dtype": "hifloat8", | ||
| 1208 | + "format": "ND", | ||
| 1209 | + "paramType": "required", | ||
| 1210 | + "shape": [ | ||
| 1211 | + -2 | ||
| 1212 | + ], | ||
| 1213 | + "format_match_mode": "FormatDefault" | ||
| 1214 | + }, | ||
| 1215 | + { | ||
| 1216 | + "name": "scale", | ||
| 1217 | + "index": 1, | ||
| 1218 | + "dtype": "float32", | ||
| 1219 | + "format": "ND", | ||
| 1220 | + "paramType": "required", | ||
| 1221 | + "shape": [ | ||
| 1222 | + -2 | ||
| 1223 | + ], | ||
| 1224 | + "format_match_mode": "FormatDefault" | ||
| 1225 | + }, | ||
| 1226 | + { | ||
| 1227 | + "name": "offset", | ||
| 1228 | + "index": 2, | ||
| 1229 | + "dtype": "float32", | ||
| 1230 | + "format": "ND", | ||
| 1231 | + "paramType": "optional", | ||
| 1232 | + "shape": [ | ||
| 1233 | + -2 | ||
| 1234 | + ], | ||
| 1235 | + "format_match_mode": "FormatDefault" | ||
| 1236 | + } | ||
| 1237 | + ], | ||
| 1238 | + "outputs": [ | ||
| 1239 | + { | ||
| 1240 | + "name": "y", | ||
| 1241 | + "index": 0, | ||
| 1242 | + "dtype": "bfloat16", | ||
| 1243 | + "format": "ND", | ||
| 1244 | + "paramType": "required", | ||
| 1245 | + "shape": [ | ||
| 1246 | + -2 | ||
| 1247 | + ], | ||
| 1248 | + "format_match_mode": "FormatDefault" | ||
| 1249 | + } | ||
| 1250 | + ], | ||
| 1251 | + "attrs": [ | ||
| 1252 | + { | ||
| 1253 | + "name": "dst_type", | ||
| 1254 | + "dtype": "int", | ||
| 1255 | + "value": null | ||
| 1256 | + }, | ||
| 1257 | + { | ||
| 1258 | + "name": "sqrt_mode", | ||
| 1259 | + "dtype": "bool", | ||
| 1260 | + "value": true | ||
| 1261 | + } | ||
| 1262 | + ] | ||
| 1263 | + }, | ||
| 1264 | + { | ||
| 1265 | + "bin_filename": "AscendAntiQuantV2_650baea70767c4bd7838a0d2g8fl03912", | ||
| 1266 | + "inputs": [ | ||
| 1267 | + { | ||
| 1268 | + "name": "x", | ||
| 1269 | + "index": 0, | ||
| 1270 | + "dtype": "float8_e5m2", | ||
| 1271 | + "format": "ND", | ||
| 1272 | + "paramType": "required", | ||
| 1273 | + "shape": [ | ||
| 1274 | + -2 | ||
| 1275 | + ], | ||
| 1276 | + "format_match_mode": "FormatDefault" | ||
| 1277 | + }, | ||
| 1278 | + { | ||
| 1279 | + "name": "scale", | ||
| 1280 | + "index": 1, | ||
| 1281 | + "dtype": "float32", | ||
| 1282 | + "format": "ND", | ||
| 1283 | + "paramType": "required", | ||
| 1284 | + "shape": [ | ||
| 1285 | + -2 | ||
| 1286 | + ], | ||
| 1287 | + "format_match_mode": "FormatDefault" | ||
| 1288 | + }, | ||
| 1289 | + { | ||
| 1290 | + "name": "offset", | ||
| 1291 | + "index": 2, | ||
| 1292 | + "dtype": "float32", | ||
| 1293 | + "format": "ND", | ||
| 1294 | + "paramType": "optional", | ||
| 1295 | + "shape": [ | ||
| 1296 | + -2 | ||
| 1297 | + ], | ||
| 1298 | + "format_match_mode": "FormatDefault" | ||
| 1299 | + } | ||
| 1300 | + ], | ||
| 1301 | + "outputs": [ | ||
| 1302 | + { | ||
| 1303 | + "name": "y", | ||
| 1304 | + "index": 0, | ||
| 1305 | + "dtype": "float16", | ||
| 1306 | + "format": "ND", | ||
| 1307 | + "paramType": "required", | ||
| 1308 | + "shape": [ | ||
| 1309 | + -2 | ||
| 1310 | + ], | ||
| 1311 | + "format_match_mode": "FormatDefault" | ||
| 1312 | + } | ||
| 1313 | + ], | ||
| 1314 | + "attrs": [ | ||
| 1315 | + { | ||
| 1316 | + "name": "dst_type", | ||
| 1317 | + "dtype": "int", | ||
| 1318 | + "value": null | ||
| 1319 | + }, | ||
| 1320 | + { | ||
| 1321 | + "name": "sqrt_mode", | ||
| 1322 | + "dtype": "bool", | ||
| 1323 | + "value": false | ||
| 1324 | + } | ||
| 1325 | + ] | ||
| 1326 | + }, | ||
| 1327 | + { | ||
| 1328 | + "bin_filename": "AscendAntiQuantV2_650baea70767c4bd7838a0d2f6ad9803", | ||
| 1329 | + "inputs": [ | ||
| 1330 | + { | ||
| 1331 | + "name": "x", | ||
| 1332 | + "index": 0, | ||
| 1333 | + "dtype": "float8_e5m2", | ||
| 1334 | + "format": "ND", | ||
| 1335 | + "paramType": "required", | ||
| 1336 | + "shape": [ | ||
| 1337 | + -2 | ||
| 1338 | + ], | ||
| 1339 | + "format_match_mode": "FormatDefault" | ||
| 1340 | + }, | ||
| 1341 | + { | ||
| 1342 | + "name": "scale", | ||
| 1343 | + "index": 1, | ||
| 1344 | + "dtype": "float32", | ||
| 1345 | + "format": "ND", | ||
| 1346 | + "paramType": "required", | ||
| 1347 | + "shape": [ | ||
| 1348 | + -2 | ||
| 1349 | + ], | ||
| 1350 | + "format_match_mode": "FormatDefault" | ||
| 1351 | + }, | ||
| 1352 | + { | ||
| 1353 | + "name": "offset", | ||
| 1354 | + "index": 2, | ||
| 1355 | + "dtype": "float32", | ||
| 1356 | + "format": "ND", | ||
| 1357 | + "paramType": "optional", | ||
| 1358 | + "shape": [ | ||
| 1359 | + -2 | ||
| 1360 | + ], | ||
| 1361 | + "format_match_mode": "FormatDefault" | ||
| 1362 | + } | ||
| 1363 | + ], | ||
| 1364 | + "outputs": [ | ||
| 1365 | + { | ||
| 1366 | + "name": "y", | ||
| 1367 | + "index": 0, | ||
| 1368 | + "dtype": "float16", | ||
| 1369 | + "format": "ND", | ||
| 1370 | + "paramType": "required", | ||
| 1371 | + "shape": [ | ||
| 1372 | + -2 | ||
| 1373 | + ], | ||
| 1374 | + "format_match_mode": "FormatDefault" | ||
| 1375 | + } | ||
| 1376 | + ], | ||
| 1377 | + "attrs": [ | ||
| 1378 | + { | ||
| 1379 | + "name": "dst_type", | ||
| 1380 | + "dtype": "int", | ||
| 1381 | + "value": null | ||
| 1382 | + }, | ||
| 1383 | + { | ||
| 1384 | + "name": "sqrt_mode", | ||
| 1385 | + "dtype": "bool", | ||
| 1386 | + "value": true | ||
| 1387 | + } | ||
| 1388 | + ] | ||
| 1389 | + }, | ||
| 1390 | + { | ||
| 1391 | + "bin_filename": "AscendAntiQuantV2_650baea70767c4bd7838a0d2f6bb5638", | ||
| 1392 | + "inputs": [ | ||
| 1393 | + { | ||
| 1394 | + "name": "x", | ||
| 1395 | + "index": 0, | ||
| 1396 | + "dtype": "float8_e5m2", | ||
| 1397 | + "format": "ND", | ||
| 1398 | + "paramType": "required", | ||
| 1399 | + "shape": [ | ||
| 1400 | + -2 | ||
| 1401 | + ], | ||
| 1402 | + "format_match_mode": "FormatDefault" | ||
| 1403 | + }, | ||
| 1404 | + { | ||
| 1405 | + "name": "scale", | ||
| 1406 | + "index": 1, | ||
| 1407 | + "dtype": "float32", | ||
| 1408 | + "format": "ND", | ||
| 1409 | + "paramType": "required", | ||
| 1410 | + "shape": [ | ||
| 1411 | + -2 | ||
| 1412 | + ], | ||
| 1413 | + "format_match_mode": "FormatDefault" | ||
| 1414 | + }, | ||
| 1415 | + { | ||
| 1416 | + "name": "offset", | ||
| 1417 | + "index": 2, | ||
| 1418 | + "dtype": "float32", | ||
| 1419 | + "format": "ND", | ||
| 1420 | + "paramType": "optional", | ||
| 1421 | + "shape": [ | ||
| 1422 | + -2 | ||
| 1423 | + ], | ||
| 1424 | + "format_match_mode": "FormatDefault" | ||
| 1425 | + } | ||
| 1426 | + ], | ||
| 1427 | + "outputs": [ | ||
| 1428 | + { | ||
| 1429 | + "name": "y", | ||
| 1430 | + "index": 0, | ||
| 1431 | + "dtype": "bfloat16", | ||
| 1432 | + "format": "ND", | ||
| 1433 | + "paramType": "required", | ||
| 1434 | + "shape": [ | ||
| 1435 | + -2 | ||
| 1436 | + ], | ||
| 1437 | + "format_match_mode": "FormatDefault" | ||
| 1438 | + } | ||
| 1439 | + ], | ||
| 1440 | + "attrs": [ | ||
| 1441 | + { | ||
| 1442 | + "name": "dst_type", | ||
| 1443 | + "dtype": "int", | ||
| 1444 | + "value": null | ||
| 1445 | + }, | ||
| 1446 | + { | ||
| 1447 | + "name": "sqrt_mode", | ||
| 1448 | + "dtype": "bool", | ||
| 1449 | + "value": false | ||
| 1450 | + } | ||
| 1451 | + ] | ||
| 1452 | + }, | ||
| 1453 | + { | ||
| 1454 | + "bin_filename": "AscendAntiQuantV2_650baea70767c4bd7838a0d2ff9380", | ||
| 1455 | + "inputs": [ | ||
| 1456 | + { | ||
| 1457 | + "name": "x", | ||
| 1458 | + "index": 0, | ||
| 1459 | + "dtype": "float8_e5m2", | ||
| 1460 | + "format": "ND", | ||
| 1461 | + "paramType": "required", | ||
| 1462 | + "shape": [ | ||
| 1463 | + -2 | ||
| 1464 | + ], | ||
| 1465 | + "format_match_mode": "FormatDefault" | ||
| 1466 | + }, | ||
| 1467 | + { | ||
| 1468 | + "name": "scale", | ||
| 1469 | + "index": 1, | ||
| 1470 | + "dtype": "float32", | ||
| 1471 | + "format": "ND", | ||
| 1472 | + "paramType": "required", | ||
| 1473 | + "shape": [ | ||
| 1474 | + -2 | ||
| 1475 | + ], | ||
| 1476 | + "format_match_mode": "FormatDefault" | ||
| 1477 | + }, | ||
| 1478 | + { | ||
| 1479 | + "name": "offset", | ||
| 1480 | + "index": 2, | ||
| 1481 | + "dtype": "float32", | ||
| 1482 | + "format": "ND", | ||
| 1483 | + "paramType": "optional", | ||
| 1484 | + "shape": [ | ||
| 1485 | + -2 | ||
| 1486 | + ], | ||
| 1487 | + "format_match_mode": "FormatDefault" | ||
| 1488 | + } | ||
| 1489 | + ], | ||
| 1490 | + "outputs": [ | ||
| 1491 | + { | ||
| 1492 | + "name": "y", | ||
| 1493 | + "index": 0, | ||
| 1494 | + "dtype": "bfloat16", | ||
| 1495 | + "format": "ND", | ||
| 1496 | + "paramType": "required", | ||
| 1497 | + "shape": [ | ||
| 1498 | + -2 | ||
| 1499 | + ], | ||
| 1500 | + "format_match_mode": "FormatDefault" | ||
| 1501 | + } | ||
| 1502 | + ], | ||
| 1503 | + "attrs": [ | ||
| 1504 | + { | ||
| 1505 | + "name": "dst_type", | ||
| 1506 | + "dtype": "int", | ||
| 1507 | + "value": null | ||
| 1508 | + }, | ||
| 1509 | + { | ||
| 1510 | + "name": "sqrt_mode", | ||
| 1511 | + "dtype": "bool", | ||
| 1512 | + "value": true | ||
| 1513 | + } | ||
| 1514 | + ] | ||
| 1515 | + }, | ||
| 1516 | + { | ||
| 1517 | + "bin_filename": "AscendAntiQuantV2_650baea70767c4bd7838a0d2g8fl03290", | ||
| 1518 | + "inputs": [ | ||
| 1519 | + { | ||
| 1520 | + "name": "x", | ||
| 1521 | + "index": 0, | ||
| 1522 | + "dtype": "float8_e4m3fn", | ||
| 1523 | + "format": "ND", | ||
| 1524 | + "paramType": "required", | ||
| 1525 | + "shape": [ | ||
| 1526 | + -2 | ||
| 1527 | + ], | ||
| 1528 | + "format_match_mode": "FormatDefault" | ||
| 1529 | + }, | ||
| 1530 | + { | ||
| 1531 | + "name": "scale", | ||
| 1532 | + "index": 1, | ||
| 1533 | + "dtype": "float32", | ||
| 1534 | + "format": "ND", | ||
| 1535 | + "paramType": "required", | ||
| 1536 | + "shape": [ | ||
| 1537 | + -2 | ||
| 1538 | + ], | ||
| 1539 | + "format_match_mode": "FormatDefault" | ||
| 1540 | + }, | ||
| 1541 | + { | ||
| 1542 | + "name": "offset", | ||
| 1543 | + "index": 2, | ||
| 1544 | + "dtype": "float32", | ||
| 1545 | + "format": "ND", | ||
| 1546 | + "paramType": "optional", | ||
| 1547 | + "shape": [ | ||
| 1548 | + -2 | ||
| 1549 | + ], | ||
| 1550 | + "format_match_mode": "FormatDefault" | ||
| 1551 | + } | ||
| 1552 | + ], | ||
| 1553 | + "outputs": [ | ||
| 1554 | + { | ||
| 1555 | + "name": "y", | ||
| 1556 | + "index": 0, | ||
| 1557 | + "dtype": "float16", | ||
| 1558 | + "format": "ND", | ||
| 1559 | + "paramType": "required", | ||
| 1560 | + "shape": [ | ||
| 1561 | + -2 | ||
| 1562 | + ], | ||
| 1563 | + "format_match_mode": "FormatDefault" | ||
| 1564 | + } | ||
| 1565 | + ], | ||
| 1566 | + "attrs": [ | ||
| 1567 | + { | ||
| 1568 | + "name": "dst_type", | ||
| 1569 | + "dtype": "int", | ||
| 1570 | + "value": null | ||
| 1571 | + }, | ||
| 1572 | + { | ||
| 1573 | + "name": "sqrt_mode", | ||
| 1574 | + "dtype": "bool", | ||
| 1575 | + "value": false | ||
| 1576 | + } | ||
| 1577 | + ] | ||
| 1578 | + }, | ||
| 1579 | + { | ||
| 1580 | + "bin_filename": "AscendAntiQuantV2_650baea70767c4bd7838a0d2k3fa9902", | ||
| 1581 | + "inputs": [ | ||
| 1582 | + { | ||
| 1583 | + "name": "x", | ||
| 1584 | + "index": 0, | ||
| 1585 | + "dtype": "float8_e4m3fn", | ||
| 1586 | + "format": "ND", | ||
| 1587 | + "paramType": "required", | ||
| 1588 | + "shape": [ | ||
| 1589 | + -2 | ||
| 1590 | + ], | ||
| 1591 | + "format_match_mode": "FormatDefault" | ||
| 1592 | + }, | ||
| 1593 | + { | ||
| 1594 | + "name": "scale", | ||
| 1595 | + "index": 1, | ||
| 1596 | + "dtype": "float32", | ||
| 1597 | + "format": "ND", | ||
| 1598 | + "paramType": "required", | ||
| 1599 | + "shape": [ | ||
| 1600 | + -2 | ||
| 1601 | + ], | ||
| 1602 | + "format_match_mode": "FormatDefault" | ||
| 1603 | + }, | ||
| 1604 | + { | ||
| 1605 | + "name": "offset", | ||
| 1606 | + "index": 2, | ||
| 1607 | + "dtype": "float32", | ||
| 1608 | + "format": "ND", | ||
| 1609 | + "paramType": "optional", | ||
| 1610 | + "shape": [ | ||
| 1611 | + -2 | ||
| 1612 | + ], | ||
| 1613 | + "format_match_mode": "FormatDefault" | ||
| 1614 | + } | ||
| 1615 | + ], | ||
| 1616 | + "outputs": [ | ||
| 1617 | + { | ||
| 1618 | + "name": "y", | ||
| 1619 | + "index": 0, | ||
| 1620 | + "dtype": "float16", | ||
| 1621 | + "format": "ND", | ||
| 1622 | + "paramType": "required", | ||
| 1623 | + "shape": [ | ||
| 1624 | + -2 | ||
| 1625 | + ], | ||
| 1626 | + "format_match_mode": "FormatDefault" | ||
| 1627 | + } | ||
| 1628 | + ], | ||
| 1629 | + "attrs": [ | ||
| 1630 | + { | ||
| 1631 | + "name": "dst_type", | ||
| 1632 | + "dtype": "int", | ||
| 1633 | + "value": null | ||
| 1634 | + }, | ||
| 1635 | + { | ||
| 1636 | + "name": "sqrt_mode", | ||
| 1637 | + "dtype": "bool", | ||
| 1638 | + "value": true | ||
| 1639 | + } | ||
| 1640 | + ] | ||
| 1641 | + }, | ||
| 1642 | + { | ||
| 1643 | + "bin_filename": "AscendAntiQuantV2_650baea70767c4bd7838a0d2f6bb5823", | ||
| 1644 | + "inputs": [ | ||
| 1645 | + { | ||
| 1646 | + "name": "x", | ||
| 1647 | + "index": 0, | ||
| 1648 | + "dtype": "float8_e4m3fn", | ||
| 1649 | + "format": "ND", | ||
| 1650 | + "paramType": "required", | ||
| 1651 | + "shape": [ | ||
| 1652 | + -2 | ||
| 1653 | + ], | ||
| 1654 | + "format_match_mode": "FormatDefault" | ||
| 1655 | + }, | ||
| 1656 | + { | ||
| 1657 | + "name": "scale", | ||
| 1658 | + "index": 1, | ||
| 1659 | + "dtype": "float32", | ||
| 1660 | + "format": "ND", | ||
| 1661 | + "paramType": "required", | ||
| 1662 | + "shape": [ | ||
| 1663 | + -2 | ||
| 1664 | + ], | ||
| 1665 | + "format_match_mode": "FormatDefault" | ||
| 1666 | + }, | ||
| 1667 | + { | ||
| 1668 | + "name": "offset", | ||
| 1669 | + "index": 2, | ||
| 1670 | + "dtype": "float32", | ||
| 1671 | + "format": "ND", | ||
| 1672 | + "paramType": "optional", | ||
| 1673 | + "shape": [ | ||
| 1674 | + -2 | ||
| 1675 | + ], | ||
| 1676 | + "format_match_mode": "FormatDefault" | ||
| 1677 | + } | ||
| 1678 | + ], | ||
| 1679 | + "outputs": [ | ||
| 1680 | + { | ||
| 1681 | + "name": "y", | ||
| 1682 | + "index": 0, | ||
| 1683 | + "dtype": "bfloat16", | ||
| 1684 | + "format": "ND", | ||
| 1685 | + "paramType": "required", | ||
| 1686 | + "shape": [ | ||
| 1687 | + -2 | ||
| 1688 | + ], | ||
| 1689 | + "format_match_mode": "FormatDefault" | ||
| 1690 | + } | ||
| 1691 | + ], | ||
| 1692 | + "attrs": [ | ||
| 1693 | + { | ||
| 1694 | + "name": "dst_type", | ||
| 1695 | + "dtype": "int", | ||
| 1696 | + "value": null | ||
| 1697 | + }, | ||
| 1698 | + { | ||
| 1699 | + "name": "sqrt_mode", | ||
| 1700 | + "dtype": "bool", | ||
| 1701 | + "value": false | ||
| 1702 | + } | ||
| 1703 | + ] | ||
| 1704 | + }, | ||
| 1705 | + { | ||
| 1706 | + "bin_filename": "AscendAntiQuantV2_650baea70767c4bd7838a0d3fg3472", | ||
| 1707 | + "inputs": [ | ||
| 1708 | + { | ||
| 1709 | + "name": "x", | ||
| 1710 | + "index": 0, | ||
| 1711 | + "dtype": "float8_e4m3fn", | ||
| 1712 | + "format": "ND", | ||
| 1713 | + "paramType": "required", | ||
| 1714 | + "shape": [ | ||
| 1715 | + -2 | ||
| 1716 | + ], | ||
| 1717 | + "format_match_mode": "FormatDefault" | ||
| 1718 | + }, | ||
| 1719 | + { | ||
| 1720 | + "name": "scale", | ||
| 1721 | + "index": 1, | ||
| 1722 | + "dtype": "float32", | ||
| 1723 | + "format": "ND", | ||
| 1724 | + "paramType": "required", | ||
| 1725 | + "shape": [ | ||
| 1726 | + -2 | ||
| 1727 | + ], | ||
| 1728 | + "format_match_mode": "FormatDefault" | ||
| 1729 | + }, | ||
| 1730 | + { | ||
| 1731 | + "name": "offset", | ||
| 1732 | + "index": 2, | ||
| 1733 | + "dtype": "float32", | ||
| 1734 | + "format": "ND", | ||
| 1735 | + "paramType": "optional", | ||
| 1736 | + "shape": [ | ||
| 1737 | + -2 | ||
| 1738 | + ], | ||
| 1739 | + "format_match_mode": "FormatDefault" | ||
| 1740 | + } | ||
| 1741 | + ], | ||
| 1742 | + "outputs": [ | ||
| 1743 | + { | ||
| 1744 | + "name": "y", | ||
| 1745 | + "index": 0, | ||
| 1746 | + "dtype": "bfloat16", | ||
| 1747 | + "format": "ND", | ||
| 1748 | + "paramType": "required", | ||
| 1749 | + "shape": [ | ||
| 1750 | + -2 | ||
| 1751 | + ], | ||
| 1752 | + "format_match_mode": "FormatDefault" | ||
| 1753 | + } | ||
| 1754 | + ], | ||
| 1755 | + "attrs": [ | ||
| 1756 | + { | ||
| 1757 | + "name": "dst_type", | ||
| 1758 | + "dtype": "int", | ||
| 1759 | + "value": null | ||
| 1760 | + }, | ||
| 1761 | + { | ||
| 1762 | + "name": "sqrt_mode", | ||
| 1763 | + "dtype": "bool", | ||
| 1764 | + "value": true | ||
| 1765 | + } | ||
| 1766 | + ] | ||
| 1767 | + } | ||
| 1768 | + ] | ||
| 1769 | +} | ||
| @@ -0,0 +1,13 @@ | |||
| 1 | +; 该文件主要影响 opc 工具 编译二进制kernel时, --simplified_key_mode 选项中填写的值,格式如下所示: | ||
| 2 | +; [某算子] | ||
| 3 | +; default=xx | ||
| 4 | +; ascendxx=xx | ||
| 5 | +; 其中,default为默认mode,ascendxx为可选mode,如果不同芯片有差异化要求时,需要配置; | ||
| 6 | +; 1)如果没有配置:非ascendC算子继续按空处理,即opc编译命令中不添加 --simplified_key_mode 选项,AscendC算子按照 simplified_key_mode=0 处理 | ||
| 7 | +; 2)如果仅有default配置:各个版本按default配置 | ||
| 8 | +; 3)如果仅有某些平台的配置,没有default配置:对应平台的按照配置的值传递,非对应平台的:非AscendC算子继续按空处理,AscendC算子按照 simplified_key_mode=0 处理 | ||
| 9 | +; 4)如果default配置和平台配置都有:对应平台的使用平台的配置,非对应的平台的以default值配置。 | ||
| 10 | +; 5)对于自定义simplified key的情况,需要在binary_simplified_key_mode.ini 文件中显式配置为None,不传入 --simplified_key_mode 选项,由opc工具和FE框架自行判断使用何种模式 | ||
| 11 | +; 6)是否是AscendC算子,由 ops/build-in/tbe/op_info_cfg/parser/ascendc_config.json 中配置的算子名字和对于的平台决定 | ||
| 12 | +[AscendAntiQuantV2] | ||
| 13 | +default=0 | ||
| @@ -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. |
| @@ -29,11 +29,18 @@ static constexpr int64_t EVEN_FACTOR = 2; | |||
| 29 | static const std::initializer_list<DataType> X_DTYPE_SUPPORT_LIST_ASCEND910B = { | 29 | static const std::initializer_list<DataType> X_DTYPE_SUPPORT_LIST_ASCEND910B = { |
| 30 | op::DataType::DT_INT4, op::DataType::DT_INT8, op::DataType::DT_INT32}; | 30 | op::DataType::DT_INT4, op::DataType::DT_INT8, op::DataType::DT_INT32}; |
| 31 | 31 | ||
| 32 | +static const std::initializer_list<DataType> X_DTYPE_SUPPORT_LIST_ASCEND950 = { | ||
| 33 | + op::DataType::DT_INT4, op::DataType::DT_INT8, op::DataType::DT_HIFLOAT8, op::DataType::DT_FLOAT8_E5M2, | ||
| 34 | + op::DataType::DT_FLOAT8_E4M3FN, op::DataType::DT_INT32}; | ||
| 35 | + | ||
| 32 | static const std::initializer_list<DataType> X_DTYPE_SUPPORT_LIST_ASCEND310P = {op::DataType::DT_INT8}; | 36 | static const std::initializer_list<DataType> X_DTYPE_SUPPORT_LIST_ASCEND310P = {op::DataType::DT_INT8}; |
| 33 | 37 | ||
| 34 | static const std::initializer_list<DataType> OUT_DTYPE_SUPPORT_LIST_ASCEND910B = { | 38 | static const std::initializer_list<DataType> OUT_DTYPE_SUPPORT_LIST_ASCEND910B = { |
| 35 | op::DataType::DT_FLOAT16, op::DataType::DT_BF16}; | 39 | op::DataType::DT_FLOAT16, op::DataType::DT_BF16}; |
| 36 | 40 | ||
| 41 | +static const std::initializer_list<DataType> OUT_DTYPE_SUPPORT_LIST_ASCEND950 = { | ||
| 42 | + op::DataType::DT_FLOAT16, op::DataType::DT_BF16}; | ||
| 43 | + | ||
| 37 | static const std::initializer_list<DataType> OUT_DTYPE_SUPPORT_LIST_ASCEND310P = {op::DataType::DT_FLOAT16}; | 44 | static const std::initializer_list<DataType> OUT_DTYPE_SUPPORT_LIST_ASCEND310P = {op::DataType::DT_FLOAT16}; |
| 38 | 45 | ||
| 39 | static const std::initializer_list<DataType> EMPTY_LIST = {}; | 46 | static const std::initializer_list<DataType> EMPTY_LIST = {}; |
| @@ -41,21 +48,26 @@ static const std::initializer_list<DataType> EMPTY_LIST = {}; | |||
| 41 | static const std::initializer_list<DataType> SCALE_OFFSET_DTYPE_SUPPORT_LIST_ASCEND910B = { | 48 | static const std::initializer_list<DataType> SCALE_OFFSET_DTYPE_SUPPORT_LIST_ASCEND910B = { |
| 42 | op::DataType::DT_FLOAT, op::DataType::DT_BF16}; | 49 | op::DataType::DT_FLOAT, op::DataType::DT_BF16}; |
| 43 | 50 | ||
| 51 | +static const std::initializer_list<DataType> SCALE_OFFSET_DTYPE_SUPPORT_LIST_ASCEND950 = { | ||
| 52 | + op::DataType::DT_FLOAT, op::DataType::DT_BF16}; | ||
| 53 | + | ||
| 44 | static const std::initializer_list<DataType> SCALE_OFFSET_DTYPE_SUPPORT_LIST_ASCEND310P = {op::DataType::DT_FLOAT}; | 54 | static const std::initializer_list<DataType> SCALE_OFFSET_DTYPE_SUPPORT_LIST_ASCEND310P = {op::DataType::DT_FLOAT}; |
| 45 | 55 | ||
| 46 | static const std::initializer_list<DataType>& GetXDtypeSupportList() | 56 | static const std::initializer_list<DataType>& GetXDtypeSupportList() |
| 47 | { | 57 | { |
| 48 | - auto curArch = GetCurrentPlatformInfo().GetCurNpuArch(); | 58 | + if (Ops::NN::AclnnUtil::IsRegbase()) { |
| 49 | - switch (curArch) { | 59 | + return X_DTYPE_SUPPORT_LIST_ASCEND950; |
| 50 | - case NpuArch::DAV_2201: | 60 | + } |
| 51 | - case NpuArch::DAV_3510: { | 61 | + NpuArch npuArch = GetCurrentPlatformInfo().GetCurNpuArch(); |
| 62 | + switch (npuArch) { | ||
| 63 | + case NpuArch::DAV_2201:{ | ||
| 52 | return X_DTYPE_SUPPORT_LIST_ASCEND910B; | 64 | return X_DTYPE_SUPPORT_LIST_ASCEND910B; |
| 53 | } | 65 | } |
| 54 | - case NpuArch::DAV_2002: | 66 | + case NpuArch::DAV_2002:{ |
| 55 | return X_DTYPE_SUPPORT_LIST_ASCEND310P; | 67 | return X_DTYPE_SUPPORT_LIST_ASCEND310P; |
| 68 | + } | ||
| 56 | default: { | 69 | default: { |
| 57 | - SocVersion socVersion = GetCurrentPlatformInfo().GetSocVersion(); | 70 | + OP_LOGE(ACLNN_ERR_RUNTIME_ERROR, "support for %u is not implemented", static_cast<uint32_t>(npuArch)); |
| 58 | - OP_LOGE(ACLNN_ERR_RUNTIME_ERROR, "support for %s is not implemented", op::ToString(socVersion).GetString()); | ||
| 59 | return EMPTY_LIST; | 71 | return EMPTY_LIST; |
| 60 | } | 72 | } |
| 61 | } | 73 | } |
| @@ -63,17 +75,19 @@ static const std::initializer_list<DataType>& GetXDtypeSupportList() | |||
| 63 | 75 | ||
| 64 | static const std::initializer_list<DataType>& GetOutDtypeSupportList() | 76 | static const std::initializer_list<DataType>& GetOutDtypeSupportList() |
| 65 | { | 77 | { |
| 66 | - auto curArch = GetCurrentPlatformInfo().GetCurNpuArch(); | 78 | + if (Ops::NN::AclnnUtil::IsRegbase()) { |
| 67 | - switch (curArch) { | 79 | + return OUT_DTYPE_SUPPORT_LIST_ASCEND950; |
| 68 | - case NpuArch::DAV_2201: | 80 | + } |
| 69 | - case NpuArch::DAV_3510: { | 81 | + NpuArch npuArch = GetCurrentPlatformInfo().GetCurNpuArch(); |
| 82 | + switch (npuArch) { | ||
| 83 | + case NpuArch::DAV_2201:{ | ||
| 70 | return OUT_DTYPE_SUPPORT_LIST_ASCEND910B; | 84 | return OUT_DTYPE_SUPPORT_LIST_ASCEND910B; |
| 71 | } | 85 | } |
| 72 | - case NpuArch::DAV_2002: | 86 | + case NpuArch::DAV_2002:{ |
| 73 | return OUT_DTYPE_SUPPORT_LIST_ASCEND310P; | 87 | return OUT_DTYPE_SUPPORT_LIST_ASCEND310P; |
| 88 | + } | ||
| 74 | default: { | 89 | default: { |
| 75 | - SocVersion socVersion = GetCurrentPlatformInfo().GetSocVersion(); | 90 | + OP_LOGE(ACLNN_ERR_RUNTIME_ERROR, "support for %u is not implemented", static_cast<uint32_t>(npuArch)); |
| 76 | - OP_LOGE(ACLNN_ERR_RUNTIME_ERROR, "support for %s is not implemented", op::ToString(socVersion).GetString()); | ||
| 77 | return EMPTY_LIST; | 91 | return EMPTY_LIST; |
| 78 | } | 92 | } |
| 79 | } | 93 | } |
| @@ -81,17 +95,19 @@ static const std::initializer_list<DataType>& GetOutDtypeSupportList() | |||
| 81 | 95 | ||
| 82 | static const std::initializer_list<DataType>& GetScaleOffsetDtypeSupportList() | 96 | static const std::initializer_list<DataType>& GetScaleOffsetDtypeSupportList() |
| 83 | { | 97 | { |
| 84 | - auto curArch = GetCurrentPlatformInfo().GetCurNpuArch(); | 98 | + if (Ops::NN::AclnnUtil::IsRegbase()) { |
| 85 | - switch (curArch) { | 99 | + return SCALE_OFFSET_DTYPE_SUPPORT_LIST_ASCEND950; |
| 86 | - case NpuArch::DAV_2201: | 100 | + } |
| 87 | - case NpuArch::DAV_3510: { | 101 | + NpuArch npuArch = GetCurrentPlatformInfo().GetCurNpuArch(); |
| 102 | + switch (npuArch) { | ||
| 103 | + case NpuArch::DAV_2201:{ | ||
| 88 | return SCALE_OFFSET_DTYPE_SUPPORT_LIST_ASCEND910B; | 104 | return SCALE_OFFSET_DTYPE_SUPPORT_LIST_ASCEND910B; |
| 89 | } | 105 | } |
| 90 | - case NpuArch::DAV_2002: | 106 | + case NpuArch::DAV_2002:{ |
| 91 | return SCALE_OFFSET_DTYPE_SUPPORT_LIST_ASCEND310P; | 107 | return SCALE_OFFSET_DTYPE_SUPPORT_LIST_ASCEND310P; |
| 108 | + } | ||
| 92 | default: { | 109 | default: { |
| 93 | - SocVersion socVersion = GetCurrentPlatformInfo().GetSocVersion(); | 110 | + OP_LOGE(ACLNN_ERR_RUNTIME_ERROR, "support for %u is not implemented", static_cast<uint32_t>(npuArch)); |
| 94 | - OP_LOGE(ACLNN_ERR_RUNTIME_ERROR, "support for %s is not implemented", op::ToString(socVersion).GetString()); | ||
| 95 | return EMPTY_LIST; | 111 | return EMPTY_LIST; |
| 96 | } | 112 | } |
| 97 | } | 113 | } |
| @@ -121,37 +137,75 @@ static bool CheckDtypeValid( | |||
| 121 | return false; | 137 | return false; |
| 122 | } | 138 | } |
| 123 | 139 | ||
| 140 | + if (scale->GetDataType() != op::DataType::DT_FLOAT && (x->GetDataType() == op::DataType::DT_HIFLOAT8 || | ||
| 141 | + x->GetDataType() == op::DataType::DT_FLOAT8_E5M2 || x->GetDataType() == op::DataType::DT_FLOAT8_E4M3FN)) { | ||
| 142 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "when x is of type %s, scale must be FLOAT", op::ToString(x->GetDataType()).GetString()); | ||
| 143 | + return false; | ||
| 144 | + } | ||
| 145 | + | ||
| 124 | return true; | 146 | return true; |
| 125 | } | 147 | } |
| 126 | 148 | ||
| 127 | static bool CheckDim(const aclTensor* y, const aclTensor* scale, const aclTensor* offset) | 149 | static bool CheckDim(const aclTensor* y, const aclTensor* scale, const aclTensor* offset) |
| 128 | { | 150 | { |
| 129 | - int64_t scaleDim = scale->GetViewShape().GetDim(0); | ||
| 130 | if (offset != nullptr) { | 151 | if (offset != nullptr) { |
| 131 | - int64_t offsetDim = offset->GetViewShape().GetDim(0); | 152 | + OP_CHECK_SHAPE_NOT_EQUAL(scale, offset, return false); |
| 132 | - if (scaleDim != offsetDim) { | ||
| 133 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "dim of scale must be the same as dim of offset"); | ||
| 134 | - return false; | ||
| 135 | - } | ||
| 136 | } | 153 | } |
| 137 | - | 154 | + // x and scale shape |
| 155 | + auto yShape = y->GetViewShape(); | ||
| 156 | + auto scaleShape = scale->GetViewShape(); | ||
| 157 | + int64_t scaleDim = scaleShape.GetDim(0); | ||
| 138 | // per-tensor | 158 | // per-tensor |
| 139 | if (scaleDim == 1) { | 159 | if (scaleDim == 1) { |
| 140 | return true; | 160 | return true; |
| 141 | } | 161 | } |
| 142 | 162 | ||
| 143 | - int64_t dimNum = static_cast<int64_t>(y->GetViewShape().GetDimNum()); | 163 | + int64_t dimNum = static_cast<int64_t>(yShape.GetDimNum()); |
| 144 | if (dimNum == 0) { | 164 | if (dimNum == 0) { |
| 145 | dimNum = 1; | 165 | dimNum = 1; |
| 146 | } | 166 | } |
| 147 | 167 | ||
| 148 | - int64_t lastDim = y->GetViewShape().GetDim(dimNum - 1); | 168 | + int64_t lastDim = yShape.GetDim(dimNum - 1); |
| 149 | if (scaleDim != lastDim) { | 169 | if (scaleDim != lastDim) { |
| 150 | OP_LOGE( | 170 | OP_LOGE( |
| 151 | ACLNN_ERR_PARAM_INVALID, "the last dim size(%ld) of out(y) must be same as scale and offset(%ld).", lastDim, | 171 | ACLNN_ERR_PARAM_INVALID, "the last dim size(%ld) of out(y) must be same as scale and offset(%ld).", lastDim, |
| 152 | scaleDim); | 172 | scaleDim); |
| 153 | return false; | 173 | return false; |
| 154 | } | 174 | } |
| 175 | + | ||
| 176 | + return true; | ||
| 177 | +} | ||
| 178 | + | ||
| 179 | +static bool CheckXAndScaleDim(const aclTensor* x, const aclTensor* scale) | ||
| 180 | +{ | ||
| 181 | + if (x->GetDataType() != op::DataType::DT_INT32) { | ||
| 182 | + return true; | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + auto scaleShape = scale->GetViewShape(); | ||
| 186 | + auto xShape = x->GetViewShape(); | ||
| 187 | + size_t scaleDimNum = static_cast<size_t>(scaleShape.GetDimNum()); | ||
| 188 | + size_t xDimNum = static_cast<size_t>(xShape.GetDimNum()); | ||
| 189 | + | ||
| 190 | + auto xLastDim = (xDimNum > 0) ? xShape.GetDim(xDimNum - 1) : 0; | ||
| 191 | + auto xSecondLastDim = (xDimNum > 1) ? xShape.GetDim(xDimNum - 2) : 0; | ||
| 192 | + auto scaleLastDim = (scaleDimNum > 0) ? scaleShape.GetDim(scaleDimNum - 1) : 0; | ||
| 193 | + | ||
| 194 | + if (xDimNum == 1 && scaleLastDim != 1 && scaleLastDim != xLastDim * INT4_NUMS_IN_INT32) { | ||
| 195 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, | ||
| 196 | + "when the dtype of x is int32 and x dim is 1, scale shape must be [1] or 8 times of x shape."); | ||
| 197 | + return false; | ||
| 198 | + } else if (xDimNum > 1) { | ||
| 199 | + if (scaleDimNum == 1 && scaleLastDim != xSecondLastDim && scaleLastDim != 1 && scaleLastDim != xLastDim * INT4_NUMS_IN_INT32) { | ||
| 200 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, | ||
| 201 | + "when the dtype of x is int32 and scale dim is 1, scale last dim must be [1], 8 times of x last dim or x -2 dim."); | ||
| 202 | + return false; | ||
| 203 | + } else if (scaleDimNum > 1 && scaleLastDim != 1 && scaleLastDim != xLastDim * INT4_NUMS_IN_INT32) { | ||
| 204 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, | ||
| 205 | + "when the dtype of x is int32, scale last dim must be [1] or 8 times of x last dim."); | ||
| 206 | + return false; | ||
| 207 | + } | ||
| 208 | + } | ||
| 155 | return true; | 209 | return true; |
| 156 | } | 210 | } |
| 157 | 211 | ||
| @@ -234,29 +288,55 @@ static bool CheckShape(const aclTensor* x, const aclTensor* y, const aclTensor* | |||
| 234 | 288 | ||
| 235 | // x的数据维度不能超过8 | 289 | // x的数据维度不能超过8 |
| 236 | OP_CHECK_MAX_DIM(x, MAX_DIM_LEN, return false); | 290 | OP_CHECK_MAX_DIM(x, MAX_DIM_LEN, return false); |
| 237 | - if (scale->GetViewShape().GetDimNum() != 1) { | 291 | + NpuArch npuArch = GetCurrentPlatformInfo().GetCurNpuArch(); |
| 238 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "scale dim num must be 1. scale:%zu", scale->GetViewShape().GetDimNum()); | 292 | + if (npuArch != NpuArch::DAV_3510) { |
| 239 | - return false; | 293 | + if (scale->GetViewShape().GetDimNum() != 1) { |
| 240 | - } | 294 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "scale dim num must be 1. scale:%zu", scale->GetViewShape().GetDimNum()); |
| 241 | - if (offset != nullptr) { | ||
| 242 | - if (offset->GetViewShape().GetDimNum() != 1) { | ||
| 243 | - OP_LOGE( | ||
| 244 | - ACLNN_ERR_PARAM_INVALID, "offset dim num must be 1. offset:%zu", offset->GetViewShape().GetDimNum()); | ||
| 245 | return false; | 295 | return false; |
| 246 | } | 296 | } |
| 247 | - OP_CHECK_BROADCAST_WITH_SHAPE(offset, y->GetViewShape(), return false); | 297 | + if (offset != nullptr) { |
| 298 | + if (offset->GetViewShape().GetDimNum() != 1) { | ||
| 299 | + OP_LOGE( | ||
| 300 | + ACLNN_ERR_PARAM_INVALID, "offset dim num must be 1. offset:%zu", offset->GetViewShape().GetDimNum()); | ||
| 301 | + return false; | ||
| 302 | + } | ||
| 303 | + OP_CHECK_BROADCAST_WITH_SHAPE(offset, y->GetViewShape(), return false); | ||
| 304 | + } | ||
| 305 | + | ||
| 306 | + CHECK_RET(CheckDim(y, scale, offset), false); | ||
| 307 | + | ||
| 308 | + OP_CHECK_BROADCAST_WITH_SHAPE(scale, y->GetViewShape(), return false); | ||
| 309 | + } else { | ||
| 310 | + if (offset != nullptr) { | ||
| 311 | + OP_CHECK_SHAPE_NOT_EQUAL(scale, offset, return false); | ||
| 312 | + } | ||
| 313 | + | ||
| 314 | + size_t dimNum = static_cast<size_t>(x->GetViewShape().GetDimNum()); | ||
| 315 | + if (dimNum == 0 && x->GetDataType() != op::DataType::DT_INT32) { | ||
| 316 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, | ||
| 317 | + "when the dtype of x is not int32, x cannot be a scalar."); | ||
| 318 | + return false; | ||
| 319 | + } | ||
| 320 | + CHECK_RET(CheckXAndScaleDim(x, scale), false); | ||
| 248 | } | 321 | } |
| 249 | 322 | ||
| 250 | - CHECK_RET(CheckDim(y, scale, offset), false); | ||
| 251 | - | ||
| 252 | - OP_CHECK_BROADCAST_WITH_SHAPE(scale, y->GetViewShape(), return false); | ||
| 253 | - | ||
| 254 | OP_LOGD("CheckShape end"); | 323 | OP_LOGD("CheckShape end"); |
| 255 | return true; | 324 | return true; |
| 256 | } | 325 | } |
| 257 | 326 | ||
| 327 | +static bool CheckAttrValid(const aclTensor* x, bool sqrtMode) | ||
| 328 | +{ | ||
| 329 | + if (sqrtMode != false && (x->GetDataType() == op::DataType::DT_HIFLOAT8 || x->GetDataType() == op::DataType::DT_FLOAT8_E5M2 | ||
| 330 | + || x->GetDataType() == op::DataType::DT_FLOAT8_E4M3FN)) { | ||
| 331 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "when x is of type %s, sqrtMode must be False", op::ToString(x->GetDataType()).GetString()); | ||
| 332 | + return false; | ||
| 333 | + } | ||
| 334 | + | ||
| 335 | + return true; | ||
| 336 | +} | ||
| 337 | + | ||
| 258 | static aclnnStatus CheckParams( | 338 | static aclnnStatus CheckParams( |
| 259 | - const aclTensor* x, const aclTensor* scale, const aclTensor* offset, int64_t dstType, const aclTensor* y) | 339 | + const aclTensor* x, const aclTensor* scale, const aclTensor* offset, int64_t dstType, bool sqrtMode, const aclTensor* y) |
| 260 | { | 340 | { |
| 261 | // 1. 检查参数是否为空指针 | 341 | // 1. 检查参数是否为空指针 |
| 262 | CHECK_RET(CheckNotNull(x, scale, y), ACLNN_ERR_PARAM_NULLPTR); | 342 | CHECK_RET(CheckNotNull(x, scale, y), ACLNN_ERR_PARAM_NULLPTR); |
| @@ -264,7 +344,10 @@ static aclnnStatus CheckParams( | |||
| 264 | // 2. 检查输入的数据类型是否在API支持的数据类型范围之内,需要根据api定义校验 | 344 | // 2. 检查输入的数据类型是否在API支持的数据类型范围之内,需要根据api定义校验 |
| 265 | CHECK_RET(CheckDtypeValid(x, scale, offset, y, dstType), ACLNN_ERR_PARAM_INVALID); | 345 | CHECK_RET(CheckDtypeValid(x, scale, offset, y, dstType), ACLNN_ERR_PARAM_INVALID); |
| 266 | 346 | ||
| 267 | - // 3. 检查shape是否满足约束 | 347 | + // 3. 检查属性是否合法 |
| 348 | + CHECK_RET(CheckAttrValid(x, sqrtMode), ACLNN_ERR_PARAM_INVALID); | ||
| 349 | + | ||
| 350 | + // 4. 检查shape是否满足约束 | ||
| 268 | CHECK_RET(CheckShape(x, y, scale, offset), ACLNN_ERR_PARAM_INVALID); | 351 | CHECK_RET(CheckShape(x, y, scale, offset), ACLNN_ERR_PARAM_INVALID); |
| 269 | 352 | ||
| 270 | return ACLNN_SUCCESS; | 353 | return ACLNN_SUCCESS; |
| @@ -308,7 +391,7 @@ aclnnStatus aclnnAscendAntiQuantGetWorkspaceSize( | |||
| 308 | CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); | 391 | CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); |
| 309 | 392 | ||
| 310 | // 固定写法,参数检查 | 393 | // 固定写法,参数检查 |
| 311 | - auto ret = CheckParams(x, scale, offset, dstType, y); | 394 | + auto ret = CheckParams(x, scale, offset, dstType, sqrtMode, y); |
| 312 | CHECK_RET(ret == ACLNN_SUCCESS, ret); | 395 | CHECK_RET(ret == ACLNN_SUCCESS, ret); |
| 313 | 396 | ||
| 314 | // 空Tensor处理 | 397 | // 空Tensor处理 |
| @@ -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. |
| @@ -26,7 +26,8 @@ namespace l0op { | |||
| 26 | OP_TYPE_REGISTER(AscendAntiQuantV2); | 26 | OP_TYPE_REGISTER(AscendAntiQuantV2); |
| 27 | 27 | ||
| 28 | static const std::initializer_list<op::DataType> AICORE_DTYPE_SUPPORT_LIST = { | 28 | static const std::initializer_list<op::DataType> AICORE_DTYPE_SUPPORT_LIST = { |
| 29 | - op::DataType::DT_INT4, op::DataType::DT_INT8}; | 29 | + op::DataType::DT_INT4, op::DataType::DT_INT8, op::DataType::DT_HIFLOAT8, op::DataType::DT_FLOAT8_E5M2, |
| 30 | + op::DataType::DT_FLOAT8_E4M3FN}; | ||
| 30 | 31 | ||
| 31 | // 根据芯片类型、dtype判断算子是否支持走aicore | 32 | // 根据芯片类型、dtype判断算子是否支持走aicore |
| 32 | static inline bool IsAiCoreSupport(const aclTensor* self) | 33 | static inline bool IsAiCoreSupport(const aclTensor* self) |
| @@ -0,0 +1,143 @@ | |||
| 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 ascend_anti_quant_v2_common.h | ||
| 13 | + * \brief ascendantiquantv2 kernel base | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | +namespace AscendAntiQuantV2 { | ||
| 23 | +using namespace AscendC; | ||
| 24 | +/** | ||
| 25 | + * \brief Type mapping helper | ||
| 26 | + */ | ||
| 27 | + | ||
| 28 | +__aicore__ inline constexpr uint32_t GetUbBlockSize() | ||
| 29 | +{ | ||
| 30 | + return 32U; | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 34 | +class AscendAntiQuantV2Base { | ||
| 35 | +public: | ||
| 36 | + __aicore__ inline AscendAntiQuantV2Base(){}; | ||
| 37 | + | ||
| 38 | +protected: | ||
| 39 | + __aicore__ inline void GetXInCopyParams( | ||
| 40 | + int64_t dim1, int64_t baseLen, int64_t xN, int64_t xLen, DataCopyExtParams& copyParams); | ||
| 41 | + __aicore__ inline void GetOutCopyParams( | ||
| 42 | + int64_t dim1, int64_t baseLen, int64_t yN, int64_t yLen, DataCopyExtParams& copyParams); | ||
| 43 | + __aicore__ inline int64_t CeilAlign(int64_t i, int64_t align); | ||
| 44 | + | ||
| 45 | +protected: | ||
| 46 | + constexpr static int32_t BLOCK_SIZE = GetUbBlockSize(); | ||
| 47 | + constexpr static int64_t INT4_NUMS_IN_INT8_SPACE = 2; | ||
| 48 | + constexpr static uint8_t MULTI_COPY_DIM = 2; | ||
| 49 | + using xCopyDtype = std::conditional_t<IsSameType<T, int4b_t>::value, uint8_t, T>; | ||
| 50 | + | ||
| 51 | +protected: | ||
| 52 | + constexpr static AscendC::Reg::CastTrait CAST_TRAIT_INT8_TO_HALF = { | ||
| 53 | + AscendC::Reg::RegLayout::ZERO, AscendC::Reg::SatMode::UNKNOWN, | ||
| 54 | + AscendC::Reg::MaskMergeMode::ZEROING, RoundMode::UNKNOWN}; | ||
| 55 | + | ||
| 56 | + constexpr static AscendC::Reg::CastTrait CAST_TRAIT_HALF_TO_FP32 = { | ||
| 57 | + AscendC::Reg::RegLayout::ZERO, AscendC::Reg::SatMode::UNKNOWN, | ||
| 58 | + AscendC::Reg::MaskMergeMode::ZEROING, RoundMode::UNKNOWN}; | ||
| 59 | + | ||
| 60 | + constexpr static AscendC::Reg::CastTrait CAST_TRAIT_BF16_TO_FP32 = { | ||
| 61 | + AscendC::Reg::RegLayout::ZERO, AscendC::Reg::SatMode::UNKNOWN, | ||
| 62 | + AscendC::Reg::MaskMergeMode::ZEROING, RoundMode::UNKNOWN}; | ||
| 63 | + | ||
| 64 | + constexpr static AscendC::Reg::CastTrait CAST_TRAIT_HIFP8_TO_FP32 = { | ||
| 65 | + AscendC::Reg::RegLayout::ZERO, AscendC::Reg::SatMode::UNKNOWN, | ||
| 66 | + AscendC::Reg::MaskMergeMode::ZEROING, RoundMode::UNKNOWN}; | ||
| 67 | + | ||
| 68 | + constexpr static AscendC::Reg::CastTrait CAST_TRAIT_FP8E5M2_TO_FP32 = { | ||
| 69 | + AscendC::Reg::RegLayout::ZERO, AscendC::Reg::SatMode::UNKNOWN, | ||
| 70 | + AscendC::Reg::MaskMergeMode::ZEROING, RoundMode::UNKNOWN}; | ||
| 71 | + | ||
| 72 | + constexpr static AscendC::Reg::CastTrait CAST_TRAIT_FP8E4M3_TO_FP32 = { | ||
| 73 | + AscendC::Reg::RegLayout::ZERO, AscendC::Reg::SatMode::UNKNOWN, | ||
| 74 | + AscendC::Reg::MaskMergeMode::ZEROING, RoundMode::UNKNOWN}; | ||
| 75 | + | ||
| 76 | + constexpr static AscendC::Reg::CastTrait CAST_TRAIT_FP32_TO_HALF = { | ||
| 77 | + AscendC::Reg::RegLayout::ZERO, AscendC::Reg::SatMode::NO_SAT, | ||
| 78 | + AscendC::Reg::MaskMergeMode::ZEROING, RoundMode::CAST_RINT}; | ||
| 79 | + | ||
| 80 | + constexpr static AscendC::Reg::CastTrait CAST_TRAIT_FP32_TO_BF16 = { | ||
| 81 | + AscendC::Reg::RegLayout::ZERO, AscendC::Reg::SatMode::NO_SAT, | ||
| 82 | + AscendC::Reg::MaskMergeMode::ZEROING, RoundMode::CAST_RINT}; | ||
| 83 | +}; | ||
| 84 | + | ||
| 85 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 86 | +__aicore__ inline int64_t AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CeilAlign(int64_t i, int64_t align) | ||
| 87 | +{ | ||
| 88 | + if (align == 0) { | ||
| 89 | + return i; | ||
| 90 | + } | ||
| 91 | + return (i + align - 1) / align * align; | ||
| 92 | +} | ||
| 93 | + | ||
| 94 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 95 | +__aicore__ inline void AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::GetOutCopyParams( | ||
| 96 | + int64_t dim1, int64_t baseLen, int64_t yN, int64_t yLen, DataCopyExtParams& copyParams) | ||
| 97 | +{ | ||
| 98 | + copyParams.blockCount = yN; | ||
| 99 | + copyParams.blockLen = yLen * sizeof(U); | ||
| 100 | + if (dim1 > yLen) { | ||
| 101 | + copyParams.dstStride = (dim1 - yLen) * sizeof(U); | ||
| 102 | + } else { | ||
| 103 | + copyParams.dstStride = 0; | ||
| 104 | + } | ||
| 105 | + if (baseLen > yLen) { | ||
| 106 | + copyParams.srcStride = (baseLen - yLen) * sizeof(U) / BLOCK_SIZE; | ||
| 107 | + } else { | ||
| 108 | + copyParams.srcStride = 0; | ||
| 109 | + } | ||
| 110 | + copyParams.rsv = 0; | ||
| 111 | +} | ||
| 112 | + | ||
| 113 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 114 | +__aicore__ inline void AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::GetXInCopyParams( | ||
| 115 | + int64_t dim1, int64_t baseLen, int64_t xN, int64_t xLen, DataCopyExtParams& copyParams) | ||
| 116 | +{ | ||
| 117 | + int64_t xLenReal = xLen; | ||
| 118 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 119 | + xLenReal = xLenReal / INT4_NUMS_IN_INT8_SPACE; | ||
| 120 | + copyParams.blockLen = xLenReal * sizeof(xCopyDtype); | ||
| 121 | + } else { | ||
| 122 | + copyParams.blockLen = xLenReal * sizeof(T); | ||
| 123 | + } | ||
| 124 | + copyParams.blockCount = xN; | ||
| 125 | + if (dim1 > xLen) { | ||
| 126 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 127 | + copyParams.srcStride = (dim1 - xLen) * sizeof(xCopyDtype) / INT4_NUMS_IN_INT8_SPACE; | ||
| 128 | + } else { | ||
| 129 | + copyParams.srcStride = (dim1 - xLen) * sizeof(T); | ||
| 130 | + } | ||
| 131 | + } else { | ||
| 132 | + copyParams.srcStride = 0; | ||
| 133 | + } | ||
| 134 | + if (baseLen > xLenReal) { | ||
| 135 | + copyParams.dstStride = (baseLen - xLenReal) * sizeof(xCopyDtype) / BLOCK_SIZE; | ||
| 136 | + } else { | ||
| 137 | + copyParams.dstStride = 0; | ||
| 138 | + } | ||
| 139 | +} | ||
| 140 | + | ||
| 141 | +} // namespace AscendAntiQuantV2 | ||
| 142 | + | ||
| 143 | + | ||
Aquant/ascend_anti_quant_v2/op_kernel/arch35/ascend_anti_quant_v2_per_channel_nddma_no_offset_regbase.h+337-0
| @@ -0,0 +1,337 @@ | |||
| 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 ascend_anti_quant_v2_per_channel_nddma_no_offset_regbase.h | ||
| 13 | + * \brief ascend_anti_quant_v2 kernel | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | +namespace AscendAntiQuantV2 { | ||
| 25 | +using namespace AscendC; | ||
| 26 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 27 | +class AscendAntiQuantV2PerChannelNddmaNoOffsetRegbase : public AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode> { | ||
| 28 | +public: | ||
| 29 | + __aicore__ inline AscendAntiQuantV2PerChannelNddmaNoOffsetRegbase(const AscendAntiQuantV2TilingData* tilingData) | ||
| 30 | + : tilingData_(tilingData){}; | ||
| 31 | + __aicore__ inline void Init(GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y); | ||
| 32 | + __aicore__ inline void Process(); | ||
| 33 | + | ||
| 34 | +private: | ||
| 35 | + __aicore__ inline void CopyXAndCompute(int64_t dataCount, int64_t offset, LocalTensor<T1>& sLocal); | ||
| 36 | + __aicore__ inline void CopyInScale(int64_t sLen, int64_t sInOffset); | ||
| 37 | + __aicore__ inline void CopyInX(int64_t xN, int64_t xLen, int64_t xInOffset); | ||
| 38 | + __aicore__ inline void CopyOutY(int64_t yN, int64_t yLen, int64_t yOutOffset); | ||
| 39 | + __aicore__ inline void Compute(int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal); | ||
| 40 | + __aicore__ inline void ParseCoreBlocks(const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockLen); | ||
| 41 | + | ||
| 42 | +private: | ||
| 43 | + using xCopyDtype = std::conditional_t<IsSameType<T, int4b_t>::value, uint8_t, T>; | ||
| 44 | + constexpr static int32_t bufferNum_ = 2; | ||
| 45 | + TPipe pipe_; | ||
| 46 | + TQue<QuePosition::VECIN, bufferNum_> inQueueX_; | ||
| 47 | + TQue<QuePosition::VECIN, bufferNum_> inQueueScale_; | ||
| 48 | + TQue<QuePosition::VECOUT, bufferNum_> outQueueY_; | ||
| 49 | + GlobalTensor<uint8_t> xGm_; | ||
| 50 | + GlobalTensor<T1> scaleGm_; | ||
| 51 | + GlobalTensor<U> yGm_; | ||
| 52 | + | ||
| 53 | + const AscendAntiQuantV2TilingData* tilingData_; | ||
| 54 | + int32_t blockIdx_ = 0; | ||
| 55 | + int64_t gmXOffset_ = 0; | ||
| 56 | + int64_t gmSOffset_ = 0; | ||
| 57 | + int64_t blockN_ = 1; | ||
| 58 | + int64_t blockLen_ = 1; | ||
| 59 | +}; | ||
| 60 | + | ||
| 61 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 62 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Init( | ||
| 63 | + GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y) | ||
| 64 | +{ | ||
| 65 | + blockIdx_ = GetBlockIdx(); | ||
| 66 | + xGm_.SetGlobalBuffer(reinterpret_cast<__gm__ uint8_t*>(x)); | ||
| 67 | + scaleGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T1*>(scale)); | ||
| 68 | + yGm_.SetGlobalBuffer(reinterpret_cast<__gm__ U*>(y)); | ||
| 69 | + | ||
| 70 | + ParseCoreBlocks(tilingData_, blockIdx_, blockN_, blockLen_); | ||
| 71 | + | ||
| 72 | + // calc n size to alloc queue | ||
| 73 | + pipe_.InitBuffer( | ||
| 74 | + inQueueX_, bufferNum_, this->CeilAlign(tilingData_->baseN * tilingData_->baseLen * sizeof(xCopyDtype), this->BLOCK_SIZE)); | ||
| 75 | + pipe_.InitBuffer( | ||
| 76 | + inQueueScale_, bufferNum_, | ||
| 77 | + this->CeilAlign(tilingData_->baseN * tilingData_->baseLen * sizeof(T1), this->BLOCK_SIZE)); | ||
| 78 | + | ||
| 79 | + pipe_.InitBuffer( | ||
| 80 | + outQueueY_, bufferNum_, this->CeilAlign(tilingData_->baseN * tilingData_->baseLen * sizeof(U), this->BLOCK_SIZE)); | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 84 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Process() | ||
| 85 | +{ | ||
| 86 | + if (blockIdx_ >= tilingData_->numCore) { | ||
| 87 | + return; | ||
| 88 | + } | ||
| 89 | + if (tilingData_->blockAxis == 0) { | ||
| 90 | + gmXOffset_ = blockIdx_ * tilingData_->blockFactor * tilingData_->dim1; | ||
| 91 | + gmSOffset_ = 0; | ||
| 92 | + } else { | ||
| 93 | + gmXOffset_ = blockIdx_ * tilingData_->blockFactor; | ||
| 94 | + gmSOffset_ = blockIdx_ * tilingData_->blockFactor; | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + // main loop with column, for scale and offset only need copy once | ||
| 98 | + int64_t lenLoopNum = blockLen_ / tilingData_->baseLen; | ||
| 99 | + int64_t lenLoopTail = blockLen_ % tilingData_->baseLen; | ||
| 100 | + for (int64_t i = 0; i < lenLoopNum; ++i) { | ||
| 101 | + CopyInScale(tilingData_->baseLen, gmSOffset_ + i * tilingData_->baseLen); | ||
| 102 | + LocalTensor<T1> sLocal = inQueueScale_.DeQue<T1>(); | ||
| 103 | + CopyXAndCompute(tilingData_->baseLen, gmXOffset_ + i * tilingData_->baseLen, sLocal); | ||
| 104 | + inQueueScale_.FreeTensor(sLocal); | ||
| 105 | + } | ||
| 106 | + if (lenLoopTail != 0) { | ||
| 107 | + CopyInScale(lenLoopTail, gmSOffset_ + lenLoopNum * tilingData_->baseLen); | ||
| 108 | + LocalTensor<T1> sLocal = inQueueScale_.DeQue<T1>(); | ||
| 109 | + CopyXAndCompute(lenLoopTail, gmXOffset_ + lenLoopNum * tilingData_->baseLen, sLocal); | ||
| 110 | + inQueueScale_.FreeTensor(sLocal); | ||
| 111 | + } | ||
| 112 | +} | ||
| 113 | + | ||
| 114 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 115 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::ParseCoreBlocks( | ||
| 116 | + const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockLen) | ||
| 117 | +{ | ||
| 118 | + if (tilingData->blockAxis == 0) { | ||
| 119 | + if (blockIdx == tilingData->numCore - 1) { | ||
| 120 | + blockN = tilingData->blockTailFactor; | ||
| 121 | + } else { | ||
| 122 | + blockN = tilingData->blockFactor; | ||
| 123 | + } | ||
| 124 | + blockLen = tilingData->dim1; | ||
| 125 | + } else if (tilingData->blockAxis == 1) { | ||
| 126 | + blockN = tilingData->dim0; | ||
| 127 | + if (blockIdx == tilingData->numCore - 1) { | ||
| 128 | + blockLen = tilingData->blockTailFactor; | ||
| 129 | + } else { | ||
| 130 | + blockLen = tilingData->blockFactor; | ||
| 131 | + } | ||
| 132 | + } | ||
| 133 | +} | ||
| 134 | + | ||
| 135 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 136 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyInScale( | ||
| 137 | + int64_t sLen, int64_t sInOffset) | ||
| 138 | +{ | ||
| 139 | + LocalTensor<T1> sLocal = inQueueScale_.AllocTensor<T1>(); | ||
| 140 | + static constexpr AscendC::MultiCopyConfig copyConfig = {false, 0, 0, false}; | ||
| 141 | + MultiCopyLoopInfo<AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM> copyLoopInfo; | ||
| 142 | + copyLoopInfo.loopSrcStride[0] = 1; | ||
| 143 | + copyLoopInfo.loopSrcStride[1] = 0; | ||
| 144 | + copyLoopInfo.loopDstStride[0] = 1; | ||
| 145 | + copyLoopInfo.loopDstStride[1] = sLen; | ||
| 146 | + copyLoopInfo.loopSize[0] = sLen; | ||
| 147 | + copyLoopInfo.loopSize[1] = tilingData_->baseN; | ||
| 148 | + | ||
| 149 | + T1 constValue = 0; | ||
| 150 | + AscendC::MultiCopyParams<T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM> copyParams = | ||
| 151 | + {copyLoopInfo, constValue}; | ||
| 152 | + AscendC::DataCopy<T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM, copyConfig>( | ||
| 153 | + sLocal, scaleGm_[sInOffset], copyParams); | ||
| 154 | + inQueueScale_.EnQue(sLocal); | ||
| 155 | +} | ||
| 156 | + | ||
| 157 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 158 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyXAndCompute( | ||
| 159 | + int64_t dataCount, int64_t offset, LocalTensor<T1>& sLocal) | ||
| 160 | +{ | ||
| 161 | + int64_t nLoopNum = blockN_ / tilingData_->baseN; | ||
| 162 | + int64_t nLoopTail = blockN_ % tilingData_->baseN; | ||
| 163 | + int64_t xOffset = offset; | ||
| 164 | + for (int64_t nIdx = 0; nIdx < nLoopNum; ++nIdx) { | ||
| 165 | + xOffset = offset + nIdx * tilingData_->baseN * tilingData_->dim1; | ||
| 166 | + CopyInX(tilingData_->baseN, dataCount, xOffset); | ||
| 167 | + Compute(tilingData_->baseN, dataCount, sLocal); | ||
| 168 | + CopyOutY(tilingData_->baseN, dataCount, xOffset); | ||
| 169 | + } | ||
| 170 | + if (nLoopTail != 0) { | ||
| 171 | + xOffset = offset + nLoopNum * tilingData_->baseN * tilingData_->dim1; | ||
| 172 | + CopyInX(nLoopTail, dataCount, xOffset); | ||
| 173 | + Compute(nLoopTail, dataCount, sLocal); | ||
| 174 | + CopyOutY(nLoopTail, dataCount, xOffset); | ||
| 175 | + } | ||
| 176 | +} | ||
| 177 | + | ||
| 178 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 179 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyInX( | ||
| 180 | + int64_t xN, int64_t xLen, int64_t xInOffset) | ||
| 181 | +{ | ||
| 182 | + int64_t xLenReal = xLen; | ||
| 183 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 184 | + xInOffset = xInOffset / this->INT4_NUMS_IN_INT8_SPACE; | ||
| 185 | + xLenReal = xLenReal / this-> INT4_NUMS_IN_INT8_SPACE; | ||
| 186 | + } | ||
| 187 | + | ||
| 188 | + LocalTensor<uint8_t> xLocal = inQueueX_.AllocTensor<uint8_t>(); | ||
| 189 | + DataCopyExtParams copyParams; | ||
| 190 | + DataCopyPadExtParams<uint8_t> padParams = {false, 0, 0, 0}; | ||
| 191 | + copyParams.blockCount = 1; | ||
| 192 | + copyParams.blockLen = xN * xLenReal * sizeof(xCopyDtype); | ||
| 193 | + copyParams.dstStride = 0; | ||
| 194 | + copyParams.srcStride = 0; | ||
| 195 | + DataCopyPad<uint8_t>(xLocal, xGm_[xInOffset], copyParams, padParams); | ||
| 196 | + inQueueX_.EnQue(xLocal); | ||
| 197 | +} | ||
| 198 | + | ||
| 199 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 200 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Compute( | ||
| 201 | + int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal) | ||
| 202 | +{ | ||
| 203 | + LocalTensor<xCopyDtype> xLocal = inQueueX_.DeQue<xCopyDtype>(); | ||
| 204 | + LocalTensor<U> outLocal = outQueueY_.AllocTensor<U>(); | ||
| 205 | + | ||
| 206 | + __local_mem__ xCopyDtype* xLocalAddr = (__local_mem__ xCopyDtype*)xLocal.GetPhyAddr(); | ||
| 207 | + __local_mem__ T1* scaleLocalAddr = (__local_mem__ T1*)sLocal.GetPhyAddr(); | ||
| 208 | + __local_mem__ U* outLocalAddr = (__local_mem__ U*)outLocal.GetPhyAddr(); | ||
| 209 | + | ||
| 210 | + uint16_t VL = AscendC::VECTOR_REG_WIDTH / sizeof(float); | ||
| 211 | + uint16_t HalfVL = VL / 2; | ||
| 212 | + | ||
| 213 | + // has offset | ||
| 214 | + __VEC_SCOPE__ | ||
| 215 | + { | ||
| 216 | + // x: int4, int8, hifp8, fp8_e5m2, fp8_e4m3 | ||
| 217 | + AscendC::Reg::RegTensor<xCopyDtype> vregX; | ||
| 218 | + AscendC::Reg::RegTensor<half> vregHalfX; | ||
| 219 | + AscendC::Reg::RegTensor<float> vregFloatX; | ||
| 220 | + // scales: fp32, bf16 | ||
| 221 | + AscendC::Reg::RegTensor<T1> vregS; | ||
| 222 | + AscendC::Reg::RegTensor<float> vregFloatS; | ||
| 223 | + // y: fp16, bf16 | ||
| 224 | + AscendC::Reg::RegTensor<float> vregFloatY; | ||
| 225 | + AscendC::Reg::RegTensor<U> vregY; | ||
| 226 | + | ||
| 227 | + AscendC::Reg::MaskReg mask; | ||
| 228 | + | ||
| 229 | + mask = AscendC::Reg::CreateMask<float>(); | ||
| 230 | + uint32_t count = dataCount * nRow; | ||
| 231 | + uint16_t vfLoopNum = (count + VL - 1) / VL; | ||
| 232 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 233 | + mask = AscendC::Reg::UpdateMask<float>(count); | ||
| 234 | + // ld and cast for x | ||
| 235 | + if constexpr (IsSameType<T, hifloat8_t>::value) { | ||
| 236 | + // hifp8 | ||
| 237 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 238 | + vregX, xLocalAddr + i * VL); | ||
| 239 | + AscendC::Reg::Cast< | ||
| 240 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HIFP8_TO_FP32>( | ||
| 241 | + vregFloatX, vregX, mask); | ||
| 242 | + } else if constexpr (IsSameType<T, fp8_e5m2_t>::value) { | ||
| 243 | + // fp8_e5m2 | ||
| 244 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 245 | + vregX, xLocalAddr + i * VL); | ||
| 246 | + AscendC::Reg::Cast< | ||
| 247 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E5M2_TO_FP32>( | ||
| 248 | + vregFloatX, vregX, mask); | ||
| 249 | + } else if constexpr (IsSameType<T, fp8_e4m3fn_t>::value) { | ||
| 250 | + // fp8_e4m3 | ||
| 251 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 252 | + vregX, xLocalAddr + i * VL); | ||
| 253 | + AscendC::Reg::Cast< | ||
| 254 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E4M3_TO_FP32>( | ||
| 255 | + vregFloatX, vregX, mask); | ||
| 256 | + } else if constexpr (IsSameType<T, int8_t>::value) { | ||
| 257 | + // int8 | ||
| 258 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 259 | + vregX, xLocalAddr + i * VL); | ||
| 260 | + AscendC::Reg::Cast< | ||
| 261 | + half, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 262 | + vregHalfX, vregX, mask); | ||
| 263 | + AscendC::Reg::Cast< | ||
| 264 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 265 | + vregFloatX, vregHalfX, mask); | ||
| 266 | + } else if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 267 | + // int4 | ||
| 268 | + AscendC::Reg::RegTensor<half> vregTmpX; | ||
| 269 | + AscendC::Reg::RegTensor<uint16_t> vregTmpU16X; | ||
| 270 | + AscendC::Reg::DataCopy<xCopyDtype, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 271 | + vregX, xLocalAddr + i * HalfVL); | ||
| 272 | + AscendC::Reg::Cast< | ||
| 273 | + half, int4x2_t, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 274 | + (AscendC::Reg::RegTensor<half>&)vregTmpU16X, | ||
| 275 | + (AscendC::Reg::RegTensor<int4x2_t>&)vregX, mask); | ||
| 276 | + AscendC::Reg::UnPack((AscendC::Reg::RegTensor<uint32_t>&)vregTmpX, vregTmpU16X); | ||
| 277 | + AscendC::Reg::Cast< | ||
| 278 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 279 | + vregFloatX, vregTmpX, mask); | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + // ld and cast for scale | ||
| 283 | + if constexpr (IsSameType<T1, float>::value) { | ||
| 284 | + // fp32 | ||
| 285 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_NORM>( | ||
| 286 | + vregFloatS, scaleLocalAddr + i * VL); | ||
| 287 | + } else if constexpr (IsSameType<T1, bfloat16_t>::value) { | ||
| 288 | + // bf16 | ||
| 289 | + AscendC::Reg::DataCopy<T1, AscendC::Reg::LoadDist::DIST_UNPACK_B16>(vregS, scaleLocalAddr + i * VL); | ||
| 290 | + AscendC::Reg::Cast< | ||
| 291 | + float, T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 292 | + vregFloatS, vregS, mask); | ||
| 293 | + } | ||
| 294 | + | ||
| 295 | + // compute | ||
| 296 | + if constexpr (SqrtMode == TPL_SQRT_MODE) { | ||
| 297 | + AscendC::Reg::Mul(vregFloatS, vregFloatS, vregFloatS, mask); | ||
| 298 | + } | ||
| 299 | + AscendC::Reg::Mul(vregFloatY, vregFloatX, vregFloatS, mask); | ||
| 300 | + | ||
| 301 | + // cast and sd for y | ||
| 302 | + if constexpr (IsSameType<U, half>::value) { | ||
| 303 | + // fp16 | ||
| 304 | + AscendC::Reg::Cast< | ||
| 305 | + half, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_HALF>( | ||
| 306 | + vregY, vregFloatY, mask); | ||
| 307 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 308 | + outLocalAddr + i * VL, vregY, mask); | ||
| 309 | + } else if constexpr (IsSameType<U, bfloat16_t>::value) { | ||
| 310 | + // bf16 | ||
| 311 | + AscendC::Reg::Cast< | ||
| 312 | + U, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_BF16>( | ||
| 313 | + vregY, vregFloatY, mask); | ||
| 314 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 315 | + outLocalAddr + i * VL, vregY, mask); | ||
| 316 | + } | ||
| 317 | + } | ||
| 318 | + } | ||
| 319 | + inQueueX_.FreeTensor(xLocal); | ||
| 320 | + outQueueY_.EnQue(outLocal); | ||
| 321 | +} | ||
| 322 | + | ||
| 323 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 324 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyOutY( | ||
| 325 | + int64_t yN, int64_t yLen, int64_t yOutOffset) | ||
| 326 | +{ | ||
| 327 | + LocalTensor<U> outLocal = outQueueY_.DeQue<U>(); | ||
| 328 | + DataCopyExtParams copyParams; | ||
| 329 | + copyParams.blockCount = 1; | ||
| 330 | + copyParams.blockLen = yN * yLen * sizeof(U); | ||
| 331 | + copyParams.dstStride = 0; | ||
| 332 | + copyParams.srcStride = 0; | ||
| 333 | + DataCopyPad<U>(yGm_[yOutOffset], outLocal, copyParams); | ||
| 334 | + outQueueY_.FreeTensor(outLocal); | ||
| 335 | +} | ||
| 336 | +} // namespace AscendAntiQuantV2 | ||
| 337 | + | ||
| @@ -0,0 +1,392 @@ | |||
| 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 ascend_anti_quant_v2_per_channel_nddma_regbase.h | ||
| 13 | + * \brief ascend_anti_quant_v2 kernel | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | +namespace AscendAntiQuantV2 { | ||
| 25 | +using namespace AscendC; | ||
| 26 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 27 | +class AscendAntiQuantV2PerChannelNddmaRegbase : public AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode> { | ||
| 28 | +public: | ||
| 29 | + __aicore__ inline AscendAntiQuantV2PerChannelNddmaRegbase(const AscendAntiQuantV2TilingData* tilingData) | ||
| 30 | + : tilingData_(tilingData){}; | ||
| 31 | + __aicore__ inline void Init(GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y); | ||
| 32 | + __aicore__ inline void Process(); | ||
| 33 | + | ||
| 34 | +private: | ||
| 35 | + __aicore__ inline void CopyXAndCompute( | ||
| 36 | + int64_t dataCount, int64_t offset, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal); | ||
| 37 | + __aicore__ inline void CopyInScale(int64_t sLen, int64_t sInOffset); | ||
| 38 | + __aicore__ inline void CopyInOffset(int64_t sLen, int64_t sInOffset); | ||
| 39 | + __aicore__ inline void CopyInX(int64_t xN, int64_t xLen, int64_t xInOffset); | ||
| 40 | + __aicore__ inline void CopyOutY(int64_t yN, int64_t yLen, int64_t yOutOffset); | ||
| 41 | + __aicore__ inline void Compute(int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal); | ||
| 42 | + __aicore__ inline void ParseCoreBlocks(const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockLen); | ||
| 43 | + | ||
| 44 | +private: | ||
| 45 | + using xCopyDtype = std::conditional_t<IsSameType<T, int4b_t>::value, uint8_t, T>; | ||
| 46 | + constexpr static int32_t bufferNum_ = 2; | ||
| 47 | + TPipe pipe_; | ||
| 48 | + TQue<QuePosition::VECIN, bufferNum_> inQueueX_; | ||
| 49 | + TQue<QuePosition::VECIN, bufferNum_> inQueueScale_; | ||
| 50 | + TQue<QuePosition::VECIN, bufferNum_> inQueueOffset_; | ||
| 51 | + TQue<QuePosition::VECOUT, bufferNum_> outQueueY_; | ||
| 52 | + GlobalTensor<uint8_t> xGm_; | ||
| 53 | + GlobalTensor<T1> scaleGm_; | ||
| 54 | + GlobalTensor<T2> offsetGm_; | ||
| 55 | + GlobalTensor<U> yGm_; | ||
| 56 | + | ||
| 57 | + const AscendAntiQuantV2TilingData* tilingData_; | ||
| 58 | + int32_t blockIdx_ = 0; | ||
| 59 | + int64_t gmXOffset_ = 0; | ||
| 60 | + int64_t gmSOffset_ = 0; | ||
| 61 | + int64_t blockN_ = 1; | ||
| 62 | + int64_t blockLen_ = 1; | ||
| 63 | +}; | ||
| 64 | + | ||
| 65 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 66 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaRegbase<T, T1, T2, U, SqrtMode>::Init( | ||
| 67 | + GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y) | ||
| 68 | +{ | ||
| 69 | + blockIdx_ = GetBlockIdx(); | ||
| 70 | + xGm_.SetGlobalBuffer(reinterpret_cast<__gm__ uint8_t*>(x)); | ||
| 71 | + scaleGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T1*>(scale)); | ||
| 72 | + offsetGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T2*>(offset)); | ||
| 73 | + yGm_.SetGlobalBuffer(reinterpret_cast<__gm__ U*>(y)); | ||
| 74 | + | ||
| 75 | + ParseCoreBlocks(tilingData_, blockIdx_, blockN_, blockLen_); | ||
| 76 | + | ||
| 77 | + // calc n size to alloc queue | ||
| 78 | + pipe_.InitBuffer( | ||
| 79 | + inQueueX_, bufferNum_, this->CeilAlign(tilingData_->baseN * tilingData_->baseLen * sizeof(xCopyDtype), this->BLOCK_SIZE)); | ||
| 80 | + pipe_.InitBuffer( | ||
| 81 | + inQueueScale_, bufferNum_, | ||
| 82 | + this->CeilAlign(tilingData_->baseN * tilingData_->baseLen * sizeof(T1), this->BLOCK_SIZE)); | ||
| 83 | + pipe_.InitBuffer( | ||
| 84 | + inQueueOffset_, bufferNum_, | ||
| 85 | + this->CeilAlign(tilingData_->baseN * tilingData_->baseLen * sizeof(T2), this->BLOCK_SIZE)); | ||
| 86 | + | ||
| 87 | + pipe_.InitBuffer( | ||
| 88 | + outQueueY_, bufferNum_, this->CeilAlign(tilingData_->baseN * tilingData_->baseLen * sizeof(U), this->BLOCK_SIZE)); | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 92 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaRegbase<T, T1, T2, U, SqrtMode>::Process() | ||
| 93 | +{ | ||
| 94 | + if (blockIdx_ >= tilingData_->numCore) { | ||
| 95 | + return; | ||
| 96 | + } | ||
| 97 | + if (tilingData_->blockAxis == 0) { | ||
| 98 | + gmXOffset_ = blockIdx_ * tilingData_->blockFactor * tilingData_->dim1; | ||
| 99 | + gmSOffset_ = 0; | ||
| 100 | + } else { | ||
| 101 | + gmXOffset_ = blockIdx_ * tilingData_->blockFactor; | ||
| 102 | + gmSOffset_ = blockIdx_ * tilingData_->blockFactor; | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + // main loop with column, for scale and offset only need copy once | ||
| 106 | + int64_t lenLoopNum = blockLen_ / tilingData_->baseLen; | ||
| 107 | + int64_t lenLoopTail = blockLen_ % tilingData_->baseLen; | ||
| 108 | + for (int64_t i = 0; i < lenLoopNum; ++i) { | ||
| 109 | + CopyInScale(tilingData_->baseLen, gmSOffset_ + i * tilingData_->baseLen); | ||
| 110 | + CopyInOffset(tilingData_->baseLen, gmSOffset_ + i * tilingData_->baseLen); | ||
| 111 | + LocalTensor<T1> sLocal = inQueueScale_.DeQue<T1>(); | ||
| 112 | + LocalTensor<T2> oLocal = inQueueOffset_.DeQue<T2>(); | ||
| 113 | + CopyXAndCompute(tilingData_->baseLen, gmXOffset_ + i * tilingData_->baseLen, sLocal, oLocal); | ||
| 114 | + inQueueScale_.FreeTensor(sLocal); | ||
| 115 | + inQueueOffset_.FreeTensor(oLocal); | ||
| 116 | + } | ||
| 117 | + if (lenLoopTail != 0) { | ||
| 118 | + CopyInScale(lenLoopTail, gmSOffset_ + lenLoopNum * tilingData_->baseLen); | ||
| 119 | + CopyInOffset(lenLoopTail, gmSOffset_ + lenLoopNum * tilingData_->baseLen); | ||
| 120 | + LocalTensor<T1> sLocal = inQueueScale_.DeQue<T1>(); | ||
| 121 | + LocalTensor<T2> oLocal = inQueueOffset_.DeQue<T2>(); | ||
| 122 | + CopyXAndCompute(lenLoopTail, gmXOffset_ + lenLoopNum * tilingData_->baseLen, sLocal, oLocal); | ||
| 123 | + inQueueScale_.FreeTensor(sLocal); | ||
| 124 | + inQueueOffset_.FreeTensor(oLocal); | ||
| 125 | + } | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 129 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaRegbase<T, T1, T2, U, SqrtMode>::ParseCoreBlocks( | ||
| 130 | + const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockLen) | ||
| 131 | +{ | ||
| 132 | + if (tilingData->blockAxis == 0) { | ||
| 133 | + if (blockIdx == tilingData->numCore - 1) { | ||
| 134 | + blockN = tilingData->blockTailFactor; | ||
| 135 | + } else { | ||
| 136 | + blockN = tilingData->blockFactor; | ||
| 137 | + } | ||
| 138 | + blockLen = tilingData->dim1; | ||
| 139 | + } else if (tilingData->blockAxis == 1) { | ||
| 140 | + blockN = tilingData->dim0; | ||
| 141 | + if (blockIdx == tilingData->numCore - 1) { | ||
| 142 | + blockLen = tilingData->blockTailFactor; | ||
| 143 | + } else { | ||
| 144 | + blockLen = tilingData->blockFactor; | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | +} | ||
| 148 | + | ||
| 149 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 150 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaRegbase<T, T1, T2, U, SqrtMode>::CopyInScale( | ||
| 151 | + int64_t sLen, int64_t sInOffset) | ||
| 152 | +{ | ||
| 153 | + LocalTensor<T1> sLocal = inQueueScale_.AllocTensor<T1>(); | ||
| 154 | + static constexpr AscendC::MultiCopyConfig copyConfig = {false, 0, 0, false}; | ||
| 155 | + MultiCopyLoopInfo<AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM> copyLoopInfo; | ||
| 156 | + copyLoopInfo.loopSrcStride[0] = 1; | ||
| 157 | + copyLoopInfo.loopSrcStride[1] = 0; | ||
| 158 | + copyLoopInfo.loopDstStride[0] = 1; | ||
| 159 | + copyLoopInfo.loopDstStride[1] = sLen; | ||
| 160 | + copyLoopInfo.loopSize[0] = sLen; | ||
| 161 | + copyLoopInfo.loopSize[1] = tilingData_->baseN; | ||
| 162 | + | ||
| 163 | + T1 constValue = 0; | ||
| 164 | + AscendC::MultiCopyParams<T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM> copyParams = | ||
| 165 | + {copyLoopInfo, constValue}; | ||
| 166 | + AscendC::DataCopy<T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM, copyConfig>( | ||
| 167 | + sLocal, scaleGm_[sInOffset], copyParams); | ||
| 168 | + inQueueScale_.EnQue(sLocal); | ||
| 169 | +} | ||
| 170 | + | ||
| 171 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 172 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaRegbase<T, T1, T2, U, SqrtMode>::CopyInOffset( | ||
| 173 | + int64_t sLen, int64_t sInOffset) | ||
| 174 | +{ | ||
| 175 | + LocalTensor<T2> oLocal = inQueueOffset_.AllocTensor<T2>(); | ||
| 176 | + static constexpr AscendC::MultiCopyConfig copyConfig = {false, 0, 0, false}; | ||
| 177 | + MultiCopyLoopInfo<AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM> copyLoopInfo; | ||
| 178 | + copyLoopInfo.loopSrcStride[0] = 1; | ||
| 179 | + copyLoopInfo.loopSrcStride[1] = 0; | ||
| 180 | + copyLoopInfo.loopDstStride[0] = 1; | ||
| 181 | + copyLoopInfo.loopDstStride[1] = sLen; | ||
| 182 | + copyLoopInfo.loopSize[0] = sLen; | ||
| 183 | + copyLoopInfo.loopSize[1] = tilingData_->baseN; | ||
| 184 | + | ||
| 185 | + T2 constValue = 0; | ||
| 186 | + AscendC::MultiCopyParams<T2, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM> copyParams = | ||
| 187 | + {copyLoopInfo, constValue}; | ||
| 188 | + AscendC::DataCopy<T2, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM, copyConfig>( | ||
| 189 | + oLocal, offsetGm_[sInOffset], copyParams); | ||
| 190 | + inQueueOffset_.EnQue(oLocal); | ||
| 191 | +} | ||
| 192 | + | ||
| 193 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 194 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaRegbase<T, T1, T2, U, SqrtMode>::CopyXAndCompute( | ||
| 195 | + int64_t dataCount, int64_t offset, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal) | ||
| 196 | +{ | ||
| 197 | + int64_t nLoopNum = blockN_ / tilingData_->baseN; | ||
| 198 | + int64_t nLoopTail = blockN_ % tilingData_->baseN; | ||
| 199 | + int64_t xOffset = offset; | ||
| 200 | + for (int64_t nIdx = 0; nIdx < nLoopNum; ++nIdx) { | ||
| 201 | + xOffset = offset + nIdx * tilingData_->baseN * tilingData_->dim1; | ||
| 202 | + CopyInX(tilingData_->baseN, dataCount, xOffset); | ||
| 203 | + Compute(tilingData_->baseN, dataCount, sLocal, oLocal); | ||
| 204 | + CopyOutY(tilingData_->baseN, dataCount, xOffset); | ||
| 205 | + } | ||
| 206 | + if (nLoopTail != 0) { | ||
| 207 | + xOffset = offset + nLoopNum * tilingData_->baseN * tilingData_->dim1; | ||
| 208 | + CopyInX(nLoopTail, dataCount, xOffset); | ||
| 209 | + Compute(nLoopTail, dataCount, sLocal, oLocal); | ||
| 210 | + CopyOutY(nLoopTail, dataCount, xOffset); | ||
| 211 | + } | ||
| 212 | +} | ||
| 213 | + | ||
| 214 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 215 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaRegbase<T, T1, T2, U, SqrtMode>::CopyInX( | ||
| 216 | + int64_t xN, int64_t xLen, int64_t xInOffset) | ||
| 217 | +{ | ||
| 218 | + int64_t xLenReal = xLen; | ||
| 219 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 220 | + xInOffset = xInOffset / this->INT4_NUMS_IN_INT8_SPACE; | ||
| 221 | + xLenReal = xLenReal / this-> INT4_NUMS_IN_INT8_SPACE; | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + LocalTensor<uint8_t> xLocal = inQueueX_.AllocTensor<uint8_t>(); | ||
| 225 | + DataCopyExtParams copyParams; | ||
| 226 | + DataCopyPadExtParams<uint8_t> padParams = {false, 0, 0, 0}; | ||
| 227 | + copyParams.blockCount = 1; | ||
| 228 | + copyParams.blockLen = xN * xLenReal * sizeof(xCopyDtype); | ||
| 229 | + copyParams.dstStride = 0; | ||
| 230 | + copyParams.srcStride = 0; | ||
| 231 | + DataCopyPad<uint8_t>(xLocal, xGm_[xInOffset], copyParams, padParams); | ||
| 232 | + inQueueX_.EnQue(xLocal); | ||
| 233 | +} | ||
| 234 | + | ||
| 235 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 236 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaRegbase<T, T1, T2, U, SqrtMode>::Compute( | ||
| 237 | + int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal) | ||
| 238 | +{ | ||
| 239 | + LocalTensor<xCopyDtype> xLocal = inQueueX_.DeQue<xCopyDtype>(); | ||
| 240 | + LocalTensor<U> outLocal = outQueueY_.AllocTensor<U>(); | ||
| 241 | + | ||
| 242 | + __local_mem__ xCopyDtype* xLocalAddr = (__local_mem__ xCopyDtype*)xLocal.GetPhyAddr(); | ||
| 243 | + __local_mem__ T1* scaleLocalAddr = (__local_mem__ T1*)sLocal.GetPhyAddr(); | ||
| 244 | + __local_mem__ U* outLocalAddr = (__local_mem__ U*)outLocal.GetPhyAddr(); | ||
| 245 | + | ||
| 246 | + uint16_t VL = AscendC::VECTOR_REG_WIDTH / sizeof(float); | ||
| 247 | + uint16_t HalfVL = VL / 2; | ||
| 248 | + __local_mem__ T2* offsetLocalAddr = (__local_mem__ T2*)oLocal.GetPhyAddr(); | ||
| 249 | + | ||
| 250 | + // has offset | ||
| 251 | + __VEC_SCOPE__ | ||
| 252 | + { | ||
| 253 | + // x: int4, int8, hifp8, fp8_e5m2, fp8_e4m3 | ||
| 254 | + AscendC::Reg::RegTensor<xCopyDtype> vregX; | ||
| 255 | + AscendC::Reg::RegTensor<half> vregHalfX; | ||
| 256 | + AscendC::Reg::RegTensor<float> vregFloatX; | ||
| 257 | + // scales: fp32, bf16 | ||
| 258 | + AscendC::Reg::RegTensor<T1> vregS; | ||
| 259 | + AscendC::Reg::RegTensor<float> vregFloatS; | ||
| 260 | + // offset: fp32, bf16 | ||
| 261 | + AscendC::Reg::RegTensor<T2> vregO; | ||
| 262 | + AscendC::Reg::RegTensor<float> vregFloatO; | ||
| 263 | + // y: fp16, bf16 | ||
| 264 | + AscendC::Reg::RegTensor<float> vregFloatY; | ||
| 265 | + AscendC::Reg::RegTensor<U> vregY; | ||
| 266 | + | ||
| 267 | + AscendC::Reg::RegTensor<float> vregTmp1; | ||
| 268 | + AscendC::Reg::MaskReg mask; | ||
| 269 | + | ||
| 270 | + mask = AscendC::Reg::CreateMask<float>(); | ||
| 271 | + uint32_t count = dataCount * nRow; | ||
| 272 | + uint16_t vfLoopNum = (count + VL - 1) / VL; | ||
| 273 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 274 | + mask = AscendC::Reg::UpdateMask<float>(count); | ||
| 275 | + // ld and cast for x | ||
| 276 | + if constexpr (IsSameType<T, hifloat8_t>::value) { | ||
| 277 | + // hifp8 | ||
| 278 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 279 | + vregX, xLocalAddr + i * VL); | ||
| 280 | + AscendC::Reg::Cast< | ||
| 281 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HIFP8_TO_FP32>( | ||
| 282 | + vregFloatX, vregX, mask); | ||
| 283 | + } else if constexpr (IsSameType<T, fp8_e5m2_t>::value) { | ||
| 284 | + // fp8_e5m2 | ||
| 285 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 286 | + vregX, xLocalAddr + i * VL); | ||
| 287 | + AscendC::Reg::Cast< | ||
| 288 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E5M2_TO_FP32>( | ||
| 289 | + vregFloatX, vregX, mask); | ||
| 290 | + } else if constexpr (IsSameType<T, fp8_e4m3fn_t>::value) { | ||
| 291 | + // fp8_e4m3 | ||
| 292 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 293 | + vregX, xLocalAddr + i * VL); | ||
| 294 | + AscendC::Reg::Cast< | ||
| 295 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E4M3_TO_FP32>( | ||
| 296 | + vregFloatX, vregX, mask); | ||
| 297 | + } else if constexpr (IsSameType<T, int8_t>::value) { | ||
| 298 | + // int8 | ||
| 299 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 300 | + vregX, xLocalAddr + i * VL); | ||
| 301 | + AscendC::Reg::Cast< | ||
| 302 | + half, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 303 | + vregHalfX, vregX, mask); | ||
| 304 | + AscendC::Reg::Cast< | ||
| 305 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 306 | + vregFloatX, vregHalfX, mask); | ||
| 307 | + } else if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 308 | + // int4 | ||
| 309 | + AscendC::Reg::RegTensor<half> vregTmpX; | ||
| 310 | + AscendC::Reg::RegTensor<uint16_t> vregTmpU16X; | ||
| 311 | + AscendC::Reg::DataCopy<xCopyDtype, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 312 | + vregX, xLocalAddr + i * HalfVL); | ||
| 313 | + AscendC::Reg::Cast< | ||
| 314 | + half, int4x2_t, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 315 | + (AscendC::Reg::RegTensor<half>&)vregTmpU16X, | ||
| 316 | + (AscendC::Reg::RegTensor<int4x2_t>&)vregX, mask); | ||
| 317 | + AscendC::Reg::UnPack((AscendC::Reg::RegTensor<uint32_t>&)vregTmpX, vregTmpU16X); | ||
| 318 | + AscendC::Reg::Cast< | ||
| 319 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 320 | + vregFloatX, vregTmpX, mask); | ||
| 321 | + } | ||
| 322 | + | ||
| 323 | + // ld and cast for scale | ||
| 324 | + if constexpr (IsSameType<T1, float>::value) { | ||
| 325 | + // fp32 | ||
| 326 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_NORM>( | ||
| 327 | + vregFloatS, scaleLocalAddr + i * VL); | ||
| 328 | + } else if constexpr (IsSameType<T1, bfloat16_t>::value) { | ||
| 329 | + // bf16 | ||
| 330 | + AscendC::Reg::DataCopy<T1, AscendC::Reg::LoadDist::DIST_UNPACK_B16>(vregS, scaleLocalAddr + i * VL); | ||
| 331 | + AscendC::Reg::Cast< | ||
| 332 | + float, T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 333 | + vregFloatS, vregS, mask); | ||
| 334 | + } | ||
| 335 | + | ||
| 336 | + // ld and cast for offset | ||
| 337 | + if constexpr (IsSameType<T2, float>::value) { | ||
| 338 | + // fp32 | ||
| 339 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_NORM>( | ||
| 340 | + vregFloatO, offsetLocalAddr + i * VL); | ||
| 341 | + } else if constexpr (IsSameType<T2, bfloat16_t>::value) { | ||
| 342 | + // bf16 | ||
| 343 | + AscendC::Reg::DataCopy<T2, AscendC::Reg::LoadDist::DIST_UNPACK_B16>(vregO, offsetLocalAddr + i * VL); | ||
| 344 | + AscendC::Reg::Cast< | ||
| 345 | + float, T2, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 346 | + vregFloatO, vregO, mask); | ||
| 347 | + } | ||
| 348 | + | ||
| 349 | + // compute | ||
| 350 | + AscendC::Reg::Add<float, AscendC::Reg::MaskMergeMode::ZEROING>(vregTmp1, vregFloatX, vregFloatO, mask); | ||
| 351 | + if constexpr (SqrtMode == TPL_SQRT_MODE) { | ||
| 352 | + AscendC::Reg::Mul(vregFloatS, vregFloatS, vregFloatS, mask); | ||
| 353 | + } | ||
| 354 | + AscendC::Reg::Mul(vregFloatY, vregTmp1, vregFloatS, mask); | ||
| 355 | + | ||
| 356 | + // cast and sd for y | ||
| 357 | + if constexpr (IsSameType<U, half>::value) { | ||
| 358 | + // fp16 | ||
| 359 | + AscendC::Reg::Cast< | ||
| 360 | + half, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_HALF>( | ||
| 361 | + vregY, vregFloatY, mask); | ||
| 362 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 363 | + outLocalAddr + i * VL, vregY, mask); | ||
| 364 | + } else if constexpr (IsSameType<U, bfloat16_t>::value) { | ||
| 365 | + // bf16 | ||
| 366 | + AscendC::Reg::Cast< | ||
| 367 | + U, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_BF16>( | ||
| 368 | + vregY, vregFloatY, mask); | ||
| 369 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 370 | + outLocalAddr + i * VL, vregY, mask); | ||
| 371 | + } | ||
| 372 | + } | ||
| 373 | + } | ||
| 374 | + inQueueX_.FreeTensor(xLocal); | ||
| 375 | + outQueueY_.EnQue(outLocal); | ||
| 376 | +} | ||
| 377 | + | ||
| 378 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 379 | +__aicore__ inline void AscendAntiQuantV2PerChannelNddmaRegbase<T, T1, T2, U, SqrtMode>::CopyOutY( | ||
| 380 | + int64_t yN, int64_t yLen, int64_t yOutOffset) | ||
| 381 | +{ | ||
| 382 | + LocalTensor<U> outLocal = outQueueY_.DeQue<U>(); | ||
| 383 | + DataCopyExtParams copyParams; | ||
| 384 | + copyParams.blockCount = 1; | ||
| 385 | + copyParams.blockLen = yN * yLen * sizeof(U); | ||
| 386 | + copyParams.dstStride = 0; | ||
| 387 | + copyParams.srcStride = 0; | ||
| 388 | + DataCopyPad<U>(yGm_[yOutOffset], outLocal, copyParams); | ||
| 389 | + outQueueY_.FreeTensor(outLocal); | ||
| 390 | +} | ||
| 391 | +} // namespace AscendAntiQuantV2 | ||
| 392 | + | ||
Aquant/ascend_anti_quant_v2/op_kernel/arch35/ascend_anti_quant_v2_per_channel_no_offset_regbase.h+323-0
| @@ -0,0 +1,323 @@ | |||
| 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 ascend_anti_quant_v2_per_channel_no_offset_regbase.h | ||
| 13 | + * \brief ascendantiquantv2 kernel | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +namespace AscendAntiQuantV2 { | ||
| 26 | +using namespace AscendC; | ||
| 27 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 28 | +class AscendAntiQuantV2PerChannelNoOffsetRegbase : public AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode> { | ||
| 29 | +public: | ||
| 30 | + __aicore__ inline AscendAntiQuantV2PerChannelNoOffsetRegbase(const AscendAntiQuantV2TilingData* tilingData) | ||
| 31 | + : tilingData_(tilingData){}; | ||
| 32 | + __aicore__ inline void Init(GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y); | ||
| 33 | + __aicore__ inline void Process(); | ||
| 34 | + | ||
| 35 | +private: | ||
| 36 | + __aicore__ inline void CopyXAndCompute(int64_t dataCount, int64_t offset, LocalTensor<T1>& sLocal); | ||
| 37 | + __aicore__ inline void CopyInScale(int64_t sLen, int64_t sInOffset); | ||
| 38 | + __aicore__ inline void ParseCoreBlocks(const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockLen); | ||
| 39 | + __aicore__ inline void CopyInX(int64_t xN, int64_t xLen, int64_t xInOffset); | ||
| 40 | + __aicore__ inline void CopyOutY(int64_t yN, int64_t yLen, int64_t yOutOffset); | ||
| 41 | + __aicore__ inline void Compute(int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal); | ||
| 42 | + | ||
| 43 | +private: | ||
| 44 | + using xCopyDtype = std::conditional_t<IsSameType<T, int4b_t>::value, uint8_t, T>; | ||
| 45 | + constexpr static int32_t bufferNum_ = 2; | ||
| 46 | + TPipe pipe_; | ||
| 47 | + TQue<QuePosition::VECIN, bufferNum_> inQueueX_; | ||
| 48 | + TQue<QuePosition::VECIN, bufferNum_> inQueueScale_; | ||
| 49 | + TQue<QuePosition::VECOUT, bufferNum_> outQueueY_; | ||
| 50 | + GlobalTensor<uint8_t> xGm_; | ||
| 51 | + GlobalTensor<T1> scaleGm_; | ||
| 52 | + GlobalTensor<U> yGm_; | ||
| 53 | + | ||
| 54 | + const AscendAntiQuantV2TilingData* tilingData_; | ||
| 55 | + int32_t blockIdx_ = 0; | ||
| 56 | + int64_t gmXOffset_ = 0; | ||
| 57 | + int64_t gmSOffset_ = 0; | ||
| 58 | + int64_t blockN_ = 1; | ||
| 59 | + int64_t blockLen_ = 1; | ||
| 60 | +}; | ||
| 61 | + | ||
| 62 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 63 | +__aicore__ inline void AscendAntiQuantV2PerChannelNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Init( | ||
| 64 | + GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y) | ||
| 65 | +{ | ||
| 66 | + blockIdx_ = GetBlockIdx(); | ||
| 67 | + xGm_.SetGlobalBuffer(reinterpret_cast<__gm__ uint8_t*>(x)); | ||
| 68 | + scaleGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T1*>(scale)); | ||
| 69 | + yGm_.SetGlobalBuffer(reinterpret_cast<__gm__ U*>(y)); | ||
| 70 | + | ||
| 71 | + ParseCoreBlocks(tilingData_, blockIdx_, blockN_, blockLen_); | ||
| 72 | + | ||
| 73 | + // calc n size to alloc queue | ||
| 74 | + pipe_.InitBuffer(inQueueX_, bufferNum_, tilingData_->baseN * tilingData_->baseLen * sizeof(xCopyDtype)); | ||
| 75 | + pipe_.InitBuffer(inQueueScale_, bufferNum_, tilingData_->baseLen * sizeof(T1)); | ||
| 76 | + | ||
| 77 | + pipe_.InitBuffer(outQueueY_, bufferNum_, tilingData_->baseN * tilingData_->baseLen * sizeof(U)); | ||
| 78 | +} | ||
| 79 | + | ||
| 80 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 81 | +__aicore__ inline void AscendAntiQuantV2PerChannelNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Process() | ||
| 82 | +{ | ||
| 83 | + if (blockIdx_ >= tilingData_->numCore) { | ||
| 84 | + return; | ||
| 85 | + } | ||
| 86 | + if (tilingData_->blockAxis == 0) { | ||
| 87 | + gmXOffset_ = blockIdx_ * tilingData_->blockFactor * tilingData_->dim1; | ||
| 88 | + gmSOffset_ = 0; | ||
| 89 | + } else { | ||
| 90 | + gmXOffset_ = blockIdx_ * tilingData_->blockFactor; | ||
| 91 | + gmSOffset_ = blockIdx_ * tilingData_->blockFactor; | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + // main loop with column, for scale and offset only need copy once | ||
| 95 | + int64_t lenLoopNum = blockLen_ / tilingData_->baseLen; | ||
| 96 | + int64_t lenLoopTail = blockLen_ % tilingData_->baseLen; | ||
| 97 | + for (int64_t i = 0; i < lenLoopNum; ++i) { | ||
| 98 | + CopyInScale(tilingData_->baseLen, gmSOffset_ + i * tilingData_->baseLen); | ||
| 99 | + LocalTensor<T1> sLocal = inQueueScale_.DeQue<T1>(); | ||
| 100 | + CopyXAndCompute(tilingData_->baseLen, gmXOffset_ + i * tilingData_->baseLen, sLocal); | ||
| 101 | + inQueueScale_.FreeTensor(sLocal); | ||
| 102 | + } | ||
| 103 | + if (lenLoopTail != 0) { | ||
| 104 | + CopyInScale(lenLoopTail, gmSOffset_ + lenLoopNum * tilingData_->baseLen); | ||
| 105 | + LocalTensor<T1> sLocal = inQueueScale_.DeQue<T1>(); | ||
| 106 | + CopyXAndCompute(lenLoopTail, gmXOffset_ + lenLoopNum * tilingData_->baseLen, sLocal); | ||
| 107 | + inQueueScale_.FreeTensor(sLocal); | ||
| 108 | + } | ||
| 109 | +} | ||
| 110 | + | ||
| 111 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 112 | +__aicore__ inline void AscendAntiQuantV2PerChannelNoOffsetRegbase<T, T1, T2, U, SqrtMode>::ParseCoreBlocks( | ||
| 113 | + const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockLen) | ||
| 114 | +{ | ||
| 115 | + if (tilingData->blockAxis == 0) { | ||
| 116 | + if (blockIdx == tilingData->numCore - 1) { | ||
| 117 | + blockN = tilingData->blockTailFactor; | ||
| 118 | + } else { | ||
| 119 | + blockN = tilingData->blockFactor; | ||
| 120 | + } | ||
| 121 | + blockLen = tilingData->dim1; | ||
| 122 | + } else if (tilingData->blockAxis == 1) { | ||
| 123 | + blockN = tilingData->dim0; | ||
| 124 | + if (blockIdx == tilingData->numCore - 1) { | ||
| 125 | + blockLen = tilingData->blockTailFactor; | ||
| 126 | + } else { | ||
| 127 | + blockLen = tilingData->blockFactor; | ||
| 128 | + } | ||
| 129 | + } | ||
| 130 | +} | ||
| 131 | + | ||
| 132 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 133 | +__aicore__ inline void AscendAntiQuantV2PerChannelNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyInScale( | ||
| 134 | + int64_t sLen, int64_t sInOffset) | ||
| 135 | +{ | ||
| 136 | + DataCopyExtParams copyParams; | ||
| 137 | + copyParams.blockCount = 1; | ||
| 138 | + copyParams.blockLen = sLen * sizeof(T1); | ||
| 139 | + copyParams.dstStride = 0; | ||
| 140 | + copyParams.srcStride = 0; | ||
| 141 | + copyParams.rsv = 0; | ||
| 142 | + LocalTensor<T1> sLocal = inQueueScale_.AllocTensor<T1>(); | ||
| 143 | + DataCopyPad(sLocal, scaleGm_[sInOffset], copyParams, {false, 0, 0, 0}); | ||
| 144 | + inQueueScale_.EnQue(sLocal); | ||
| 145 | +} | ||
| 146 | + | ||
| 147 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 148 | +__aicore__ inline void AscendAntiQuantV2PerChannelNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyXAndCompute( | ||
| 149 | + int64_t dataCount, int64_t offset, LocalTensor<T1>& sLocal) | ||
| 150 | +{ | ||
| 151 | + int64_t nLoopNum = blockN_ / tilingData_->baseN; | ||
| 152 | + int64_t nLoopTail = blockN_ % tilingData_->baseN; | ||
| 153 | + int64_t xOffset = offset; | ||
| 154 | + for (int64_t nIdx = 0; nIdx < nLoopNum; ++nIdx) { | ||
| 155 | + xOffset = offset + nIdx * tilingData_->baseN * tilingData_->dim1; | ||
| 156 | + CopyInX(tilingData_->baseN, dataCount, xOffset); | ||
| 157 | + Compute(tilingData_->baseN, dataCount, sLocal); | ||
| 158 | + CopyOutY(tilingData_->baseN, dataCount, xOffset); | ||
| 159 | + } | ||
| 160 | + if (nLoopTail != 0) { | ||
| 161 | + xOffset = offset + nLoopNum * tilingData_->baseN * tilingData_->dim1; | ||
| 162 | + CopyInX(nLoopTail, dataCount, xOffset); | ||
| 163 | + Compute(nLoopTail, dataCount, sLocal); | ||
| 164 | + CopyOutY(nLoopTail, dataCount, xOffset); | ||
| 165 | + } | ||
| 166 | +} | ||
| 167 | + | ||
| 168 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 169 | +__aicore__ inline void AscendAntiQuantV2PerChannelNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyInX( | ||
| 170 | + int64_t xN, int64_t xLen, int64_t xInOffset) | ||
| 171 | +{ | ||
| 172 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 173 | + xInOffset = xInOffset >> 1; | ||
| 174 | + } | ||
| 175 | + | ||
| 176 | + LocalTensor<uint8_t> xLocal = inQueueX_.AllocTensor<uint8_t>(); | ||
| 177 | + DataCopyExtParams copyParams; | ||
| 178 | + DataCopyPadExtParams<uint8_t> padParams = {false, 0, 0, 0}; | ||
| 179 | + this->GetXInCopyParams(tilingData_->dim1, tilingData_->baseLen, xN, xLen, copyParams); | ||
| 180 | + DataCopyPad<uint8_t>(xLocal, xGm_[xInOffset], copyParams, padParams); | ||
| 181 | + inQueueX_.EnQue(xLocal); | ||
| 182 | +} | ||
| 183 | + | ||
| 184 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 185 | +__aicore__ inline void AscendAntiQuantV2PerChannelNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Compute( | ||
| 186 | + int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal) | ||
| 187 | +{ | ||
| 188 | + LocalTensor<xCopyDtype> xLocal = inQueueX_.DeQue<xCopyDtype>(); | ||
| 189 | + LocalTensor<U> outLocal = outQueueY_.AllocTensor<U>(); | ||
| 190 | + | ||
| 191 | + __local_mem__ xCopyDtype* xLocalAddr = (__local_mem__ xCopyDtype*)xLocal.GetPhyAddr(); | ||
| 192 | + __local_mem__ T1* scaleLocalAddr = (__local_mem__ T1*)sLocal.GetPhyAddr(); | ||
| 193 | + __local_mem__ U* outLocalAddr = (__local_mem__ U*)outLocal.GetPhyAddr(); | ||
| 194 | + | ||
| 195 | + uint16_t VL = AscendC::VECTOR_REG_WIDTH / sizeof(float); | ||
| 196 | + uint16_t HalfVL = VL / 2; | ||
| 197 | + uint16_t vfLoopNum = (dataCount + VL - 1) / VL; | ||
| 198 | + | ||
| 199 | + uint32_t xLocalOffset = static_cast<uint32_t>(tilingData_->baseLen); | ||
| 200 | + | ||
| 201 | + // has offset | ||
| 202 | + __VEC_SCOPE__ | ||
| 203 | + { | ||
| 204 | + // x: int4, int8, hifp8, fp8_e5m2, fp8_e4m3 | ||
| 205 | + AscendC::Reg::RegTensor<xCopyDtype> vregX; | ||
| 206 | + AscendC::Reg::RegTensor<half> vregHalfX; | ||
| 207 | + AscendC::Reg::RegTensor<float> vregFloatX; | ||
| 208 | + // scales: fp32, bf16 | ||
| 209 | + AscendC::Reg::RegTensor<T1> vregS; | ||
| 210 | + AscendC::Reg::RegTensor<float> vregFloatS; | ||
| 211 | + // y: fp16, bf16 | ||
| 212 | + AscendC::Reg::RegTensor<float> vregFloatY; | ||
| 213 | + AscendC::Reg::RegTensor<U> vregY; | ||
| 214 | + | ||
| 215 | + AscendC::Reg::MaskReg mask; | ||
| 216 | + | ||
| 217 | + mask = AscendC::Reg::CreateMask<float>(); | ||
| 218 | + for (uint16_t j = 0; j < static_cast<uint16_t>(nRow); ++j) { | ||
| 219 | + uint32_t count = dataCount; | ||
| 220 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 221 | + mask = AscendC::Reg::UpdateMask<float>(count); | ||
| 222 | + // ld and cast for x | ||
| 223 | + if constexpr (IsSameType<T, hifloat8_t>::value) { | ||
| 224 | + // hifp8 | ||
| 225 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 226 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 227 | + AscendC::Reg::Cast< | ||
| 228 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HIFP8_TO_FP32>( | ||
| 229 | + vregFloatX, vregX, mask); | ||
| 230 | + } else if constexpr (IsSameType<T, fp8_e5m2_t>::value) { | ||
| 231 | + // fp8_e5m2 | ||
| 232 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 233 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 234 | + AscendC::Reg::Cast< | ||
| 235 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E5M2_TO_FP32>( | ||
| 236 | + vregFloatX, vregX, mask); | ||
| 237 | + } else if constexpr (IsSameType<T, fp8_e4m3fn_t>::value) { | ||
| 238 | + // fp8_e4m3 | ||
| 239 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 240 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 241 | + AscendC::Reg::Cast< | ||
| 242 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E4M3_TO_FP32>( | ||
| 243 | + vregFloatX, vregX, mask); | ||
| 244 | + } else if constexpr (IsSameType<T, int8_t>::value) { | ||
| 245 | + // int8 | ||
| 246 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 247 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 248 | + AscendC::Reg::Cast< | ||
| 249 | + half, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 250 | + vregHalfX, vregX, mask); | ||
| 251 | + AscendC::Reg::Cast< | ||
| 252 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 253 | + vregFloatX, vregHalfX, mask); | ||
| 254 | + } else if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 255 | + // int4 | ||
| 256 | + AscendC::Reg::RegTensor<half> vregTmpX; | ||
| 257 | + AscendC::Reg::RegTensor<uint16_t> vregTmpU16X; | ||
| 258 | + AscendC::Reg::DataCopy<xCopyDtype, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 259 | + vregX, xLocalAddr + i * HalfVL + j * xLocalOffset); | ||
| 260 | + AscendC::Reg::Cast< | ||
| 261 | + half, int4x2_t, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 262 | + (AscendC::Reg::RegTensor<half>&)vregTmpU16X, | ||
| 263 | + (AscendC::Reg::RegTensor<int4x2_t>&)vregX, mask); | ||
| 264 | + AscendC::Reg::UnPack((AscendC::Reg::RegTensor<uint32_t>&)vregTmpX, vregTmpU16X); | ||
| 265 | + AscendC::Reg::Cast< | ||
| 266 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 267 | + vregFloatX, vregTmpX, mask); | ||
| 268 | + } | ||
| 269 | + | ||
| 270 | + // ld and cast for scale | ||
| 271 | + if constexpr (IsSameType<T1, float>::value) { | ||
| 272 | + // fp32 | ||
| 273 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_NORM>( | ||
| 274 | + vregFloatS, scaleLocalAddr + i * VL); | ||
| 275 | + } else if constexpr (IsSameType<T1, bfloat16_t>::value) { | ||
| 276 | + // bf16 | ||
| 277 | + AscendC::Reg::DataCopy<T1, AscendC::Reg::LoadDist::DIST_UNPACK_B16>(vregS, scaleLocalAddr + i * VL); | ||
| 278 | + AscendC::Reg::Cast< | ||
| 279 | + float, T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 280 | + vregFloatS, vregS, mask); | ||
| 281 | + } | ||
| 282 | + | ||
| 283 | + // compute | ||
| 284 | + if constexpr (SqrtMode == TPL_SQRT_MODE) { | ||
| 285 | + AscendC::Reg::Mul(vregFloatS, vregFloatS, vregFloatS, mask); | ||
| 286 | + } | ||
| 287 | + AscendC::Reg::Mul(vregFloatY, vregFloatX, vregFloatS, mask); | ||
| 288 | + | ||
| 289 | + // cast and sd for y | ||
| 290 | + if constexpr (IsSameType<U, half>::value) { | ||
| 291 | + // fp16 | ||
| 292 | + AscendC::Reg::Cast< | ||
| 293 | + half, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_HALF>( | ||
| 294 | + vregY, vregFloatY, mask); | ||
| 295 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 296 | + outLocalAddr + i * VL + j * xLocalOffset, vregY, mask); | ||
| 297 | + } else if constexpr (IsSameType<U, bfloat16_t>::value) { | ||
| 298 | + // bf16 | ||
| 299 | + AscendC::Reg::Cast< | ||
| 300 | + U, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_BF16>( | ||
| 301 | + vregY, vregFloatY, mask); | ||
| 302 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 303 | + outLocalAddr + i * VL + j * xLocalOffset, vregY, mask); | ||
| 304 | + } | ||
| 305 | + } | ||
| 306 | + } | ||
| 307 | + } | ||
| 308 | + inQueueX_.FreeTensor(xLocal); | ||
| 309 | + outQueueY_.EnQue(outLocal); | ||
| 310 | +} | ||
| 311 | + | ||
| 312 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 313 | +__aicore__ inline void AscendAntiQuantV2PerChannelNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyOutY( | ||
| 314 | + int64_t yN, int64_t yLen, int64_t yOutOffset) | ||
| 315 | +{ | ||
| 316 | + LocalTensor<U> outLocal = outQueueY_.DeQue<U>(); | ||
| 317 | + DataCopyExtParams copyParams; | ||
| 318 | + this->GetOutCopyParams(tilingData_->dim1, tilingData_->baseLen, yN, yLen, copyParams); | ||
| 319 | + DataCopyPad<U>(yGm_[yOutOffset], outLocal, copyParams); | ||
| 320 | + outQueueY_.FreeTensor(outLocal); | ||
| 321 | +} | ||
| 322 | +} // namespace AscendAntiQuantV2 | ||
| 323 | + | ||
| @@ -0,0 +1,369 @@ | |||
| 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 ascend_anti_quant_v2_per_channel_regbase.h | ||
| 13 | + * \brief ascendantiquantv2 kernel | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +namespace AscendAntiQuantV2 { | ||
| 26 | +using namespace AscendC; | ||
| 27 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 28 | +class AscendAntiQuantV2PerChannelRegbase : public AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode> { | ||
| 29 | +public: | ||
| 30 | + __aicore__ inline AscendAntiQuantV2PerChannelRegbase(const AscendAntiQuantV2TilingData* tilingData) | ||
| 31 | + : tilingData_(tilingData){}; | ||
| 32 | + __aicore__ inline void Init(GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y); | ||
| 33 | + __aicore__ inline void Process(); | ||
| 34 | + | ||
| 35 | +private: | ||
| 36 | + __aicore__ inline void CopyXAndCompute( | ||
| 37 | + int64_t dataCount, int64_t offset, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal); | ||
| 38 | + __aicore__ inline void CopyInScale(int64_t sLen, int64_t sInOffset); | ||
| 39 | + __aicore__ inline void CopyInOffset(int64_t sLen, int64_t sInOffset); | ||
| 40 | + __aicore__ inline void ParseCoreBlocks(const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockLen); | ||
| 41 | + __aicore__ inline void CopyInX(int64_t xN, int64_t xLen, int64_t xInOffset); | ||
| 42 | + __aicore__ inline void CopyOutY(int64_t yN, int64_t yLen, int64_t yOutOffset); | ||
| 43 | + __aicore__ inline void Compute(int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal); | ||
| 44 | + | ||
| 45 | +private: | ||
| 46 | + using xCopyDtype = std::conditional_t<IsSameType<T, int4b_t>::value, uint8_t, T>; | ||
| 47 | + constexpr static int32_t bufferNum_ = 2; | ||
| 48 | + TPipe pipe_; | ||
| 49 | + TQue<QuePosition::VECIN, bufferNum_> inQueueX_; | ||
| 50 | + TQue<QuePosition::VECIN, bufferNum_> inQueueScale_; | ||
| 51 | + TQue<QuePosition::VECIN, bufferNum_> inQueueOffset_; | ||
| 52 | + TQue<QuePosition::VECOUT, bufferNum_> outQueueY_; | ||
| 53 | + GlobalTensor<uint8_t> xGm_; | ||
| 54 | + GlobalTensor<T1> scaleGm_; | ||
| 55 | + GlobalTensor<T2> offsetGm_; | ||
| 56 | + GlobalTensor<U> yGm_; | ||
| 57 | + | ||
| 58 | + const AscendAntiQuantV2TilingData* tilingData_; | ||
| 59 | + int32_t blockIdx_ = 0; | ||
| 60 | + int64_t gmXOffset_ = 0; | ||
| 61 | + int64_t gmSOffset_ = 0; | ||
| 62 | + int64_t blockN_ = 1; | ||
| 63 | + int64_t blockLen_ = 1; | ||
| 64 | +}; | ||
| 65 | + | ||
| 66 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 67 | +__aicore__ inline void AscendAntiQuantV2PerChannelRegbase<T, T1, T2, U, SqrtMode>::Init( | ||
| 68 | + GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y) | ||
| 69 | +{ | ||
| 70 | + blockIdx_ = GetBlockIdx(); | ||
| 71 | + xGm_.SetGlobalBuffer(reinterpret_cast<__gm__ uint8_t*>(x)); | ||
| 72 | + scaleGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T1*>(scale)); | ||
| 73 | + offsetGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T2*>(offset)); | ||
| 74 | + yGm_.SetGlobalBuffer(reinterpret_cast<__gm__ U*>(y)); | ||
| 75 | + | ||
| 76 | + ParseCoreBlocks(tilingData_, blockIdx_, blockN_, blockLen_); | ||
| 77 | + | ||
| 78 | + // calc n size to alloc queue | ||
| 79 | + pipe_.InitBuffer(inQueueX_, bufferNum_, tilingData_->baseN * tilingData_->baseLen * sizeof(xCopyDtype)); | ||
| 80 | + pipe_.InitBuffer(inQueueScale_, bufferNum_, tilingData_->baseLen * sizeof(T1)); | ||
| 81 | + pipe_.InitBuffer(inQueueOffset_, bufferNum_, tilingData_->baseLen * sizeof(T2)); | ||
| 82 | + | ||
| 83 | + pipe_.InitBuffer(outQueueY_, bufferNum_, tilingData_->baseN * tilingData_->baseLen * sizeof(U)); | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 87 | +__aicore__ inline void AscendAntiQuantV2PerChannelRegbase<T, T1, T2, U, SqrtMode>::Process() | ||
| 88 | +{ | ||
| 89 | + if (blockIdx_ >= tilingData_->numCore) { | ||
| 90 | + return; | ||
| 91 | + } | ||
| 92 | + if (tilingData_->blockAxis == 0) { | ||
| 93 | + gmXOffset_ = blockIdx_ * tilingData_->blockFactor * tilingData_->dim1; | ||
| 94 | + gmSOffset_ = 0; | ||
| 95 | + } else { | ||
| 96 | + gmXOffset_ = blockIdx_ * tilingData_->blockFactor; | ||
| 97 | + gmSOffset_ = blockIdx_ * tilingData_->blockFactor; | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + // main loop with column, for scale and offset only need copy once | ||
| 101 | + int64_t lenLoopNum = blockLen_ / tilingData_->baseLen; | ||
| 102 | + int64_t lenLoopTail = blockLen_ % tilingData_->baseLen; | ||
| 103 | + for (int64_t i = 0; i < lenLoopNum; ++i) { | ||
| 104 | + CopyInScale(tilingData_->baseLen, gmSOffset_ + i * tilingData_->baseLen); | ||
| 105 | + CopyInOffset(tilingData_->baseLen, gmSOffset_ + i * tilingData_->baseLen); | ||
| 106 | + LocalTensor<T1> sLocal = inQueueScale_.DeQue<T1>(); | ||
| 107 | + LocalTensor<T2> oLocal = inQueueOffset_.DeQue<T2>(); | ||
| 108 | + CopyXAndCompute(tilingData_->baseLen, gmXOffset_ + i * tilingData_->baseLen, sLocal, oLocal); | ||
| 109 | + inQueueScale_.FreeTensor(sLocal); | ||
| 110 | + inQueueOffset_.FreeTensor(oLocal); | ||
| 111 | + } | ||
| 112 | + if (lenLoopTail != 0) { | ||
| 113 | + CopyInScale(lenLoopTail, gmSOffset_ + lenLoopNum * tilingData_->baseLen); | ||
| 114 | + CopyInOffset(lenLoopTail, gmSOffset_ + lenLoopNum * tilingData_->baseLen); | ||
| 115 | + LocalTensor<T1> sLocal = inQueueScale_.DeQue<T1>(); | ||
| 116 | + LocalTensor<T2> oLocal = inQueueOffset_.DeQue<T2>(); | ||
| 117 | + CopyXAndCompute(lenLoopTail, gmXOffset_ + lenLoopNum * tilingData_->baseLen, sLocal, oLocal); | ||
| 118 | + inQueueScale_.FreeTensor(sLocal); | ||
| 119 | + inQueueOffset_.FreeTensor(oLocal); | ||
| 120 | + } | ||
| 121 | +} | ||
| 122 | + | ||
| 123 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 124 | +__aicore__ inline void AscendAntiQuantV2PerChannelRegbase<T, T1, T2, U, SqrtMode>::ParseCoreBlocks( | ||
| 125 | + const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockLen) | ||
| 126 | +{ | ||
| 127 | + if (tilingData->blockAxis == 0) { | ||
| 128 | + if (blockIdx == tilingData->numCore - 1) { | ||
| 129 | + blockN = tilingData->blockTailFactor; | ||
| 130 | + } else { | ||
| 131 | + blockN = tilingData->blockFactor; | ||
| 132 | + } | ||
| 133 | + blockLen = tilingData->dim1; | ||
| 134 | + } else if (tilingData->blockAxis == 1) { | ||
| 135 | + blockN = tilingData->dim0; | ||
| 136 | + if (blockIdx == tilingData->numCore - 1) { | ||
| 137 | + blockLen = tilingData->blockTailFactor; | ||
| 138 | + } else { | ||
| 139 | + blockLen = tilingData->blockFactor; | ||
| 140 | + } | ||
| 141 | + } | ||
| 142 | +} | ||
| 143 | + | ||
| 144 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 145 | +__aicore__ inline void AscendAntiQuantV2PerChannelRegbase<T, T1, T2, U, SqrtMode>::CopyInScale( | ||
| 146 | + int64_t sLen, int64_t sInOffset) | ||
| 147 | +{ | ||
| 148 | + DataCopyExtParams copyParams; | ||
| 149 | + copyParams.blockCount = 1; | ||
| 150 | + copyParams.blockLen = sLen * sizeof(T1); | ||
| 151 | + copyParams.dstStride = 0; | ||
| 152 | + copyParams.srcStride = 0; | ||
| 153 | + copyParams.rsv = 0; | ||
| 154 | + LocalTensor<T1> sLocal = inQueueScale_.AllocTensor<T1>(); | ||
| 155 | + DataCopyPad(sLocal, scaleGm_[sInOffset], copyParams, {false, 0, 0, 0}); | ||
| 156 | + inQueueScale_.EnQue(sLocal); | ||
| 157 | +} | ||
| 158 | + | ||
| 159 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 160 | +__aicore__ inline void AscendAntiQuantV2PerChannelRegbase<T, T1, T2, U, SqrtMode>::CopyInOffset( | ||
| 161 | + int64_t sLen, int64_t sInOffset) | ||
| 162 | +{ | ||
| 163 | + DataCopyExtParams copyParams; | ||
| 164 | + copyParams.blockCount = 1; | ||
| 165 | + copyParams.blockLen = sLen * sizeof(T2); | ||
| 166 | + copyParams.dstStride = 0; | ||
| 167 | + copyParams.srcStride = 0; | ||
| 168 | + copyParams.rsv = 0; | ||
| 169 | + LocalTensor<T2> oLocal = inQueueOffset_.AllocTensor<T2>(); | ||
| 170 | + DataCopyPad(oLocal, offsetGm_[sInOffset], copyParams, {false, 0, 0, 0}); | ||
| 171 | + inQueueOffset_.EnQue(oLocal); | ||
| 172 | +} | ||
| 173 | + | ||
| 174 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 175 | +__aicore__ inline void AscendAntiQuantV2PerChannelRegbase<T, T1, T2, U, SqrtMode>::CopyXAndCompute( | ||
| 176 | + int64_t dataCount, int64_t offset, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal) | ||
| 177 | +{ | ||
| 178 | + int64_t nLoopNum = blockN_ / tilingData_->baseN; | ||
| 179 | + int64_t nLoopTail = blockN_ % tilingData_->baseN; | ||
| 180 | + int64_t xOffset = offset; | ||
| 181 | + for (int64_t nIdx = 0; nIdx < nLoopNum; ++nIdx) { | ||
| 182 | + xOffset = offset + nIdx * tilingData_->baseN * tilingData_->dim1; | ||
| 183 | + CopyInX(tilingData_->baseN, dataCount, xOffset); | ||
| 184 | + Compute(tilingData_->baseN, dataCount, sLocal, oLocal); | ||
| 185 | + CopyOutY(tilingData_->baseN, dataCount, xOffset); | ||
| 186 | + } | ||
| 187 | + if (nLoopTail != 0) { | ||
| 188 | + xOffset = offset + nLoopNum * tilingData_->baseN * tilingData_->dim1; | ||
| 189 | + CopyInX(nLoopTail, dataCount, xOffset); | ||
| 190 | + Compute(nLoopTail, dataCount, sLocal, oLocal); | ||
| 191 | + CopyOutY(nLoopTail, dataCount, xOffset); | ||
| 192 | + } | ||
| 193 | +} | ||
| 194 | + | ||
| 195 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 196 | +__aicore__ inline void AscendAntiQuantV2PerChannelRegbase<T, T1, T2, U, SqrtMode>::CopyInX( | ||
| 197 | + int64_t xN, int64_t xLen, int64_t xInOffset) | ||
| 198 | +{ | ||
| 199 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 200 | + xInOffset = xInOffset >> 1; | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + LocalTensor<uint8_t> xLocal = inQueueX_.AllocTensor<uint8_t>(); | ||
| 204 | + DataCopyExtParams copyParams; | ||
| 205 | + DataCopyPadExtParams<uint8_t> padParams = {false, 0, 0, 0}; | ||
| 206 | + this->GetXInCopyParams(tilingData_->dim1, tilingData_->baseLen, xN, xLen, copyParams); | ||
| 207 | + DataCopyPad<uint8_t>(xLocal, xGm_[xInOffset], copyParams, padParams); | ||
| 208 | + inQueueX_.EnQue(xLocal); | ||
| 209 | +} | ||
| 210 | + | ||
| 211 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 212 | +__aicore__ inline void AscendAntiQuantV2PerChannelRegbase<T, T1, T2, U, SqrtMode>::Compute( | ||
| 213 | + int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal) | ||
| 214 | +{ | ||
| 215 | + LocalTensor<xCopyDtype> xLocal = inQueueX_.DeQue<xCopyDtype>(); | ||
| 216 | + LocalTensor<U> outLocal = outQueueY_.AllocTensor<U>(); | ||
| 217 | + | ||
| 218 | + __local_mem__ xCopyDtype* xLocalAddr = (__local_mem__ xCopyDtype*)xLocal.GetPhyAddr(); | ||
| 219 | + __local_mem__ T1* scaleLocalAddr = (__local_mem__ T1*)sLocal.GetPhyAddr(); | ||
| 220 | + __local_mem__ T2* offsetLocalAddr = (__local_mem__ T2*)oLocal.GetPhyAddr(); | ||
| 221 | + __local_mem__ U* outLocalAddr = (__local_mem__ U*)outLocal.GetPhyAddr(); | ||
| 222 | + | ||
| 223 | + uint16_t VL = AscendC::VECTOR_REG_WIDTH / sizeof(float); | ||
| 224 | + uint16_t HalfVL = VL / 2; | ||
| 225 | + uint16_t vfLoopNum = (dataCount + VL - 1) / VL; | ||
| 226 | + | ||
| 227 | + uint32_t xLocalOffset = static_cast<uint32_t>(tilingData_->baseLen); | ||
| 228 | + | ||
| 229 | + // has offset | ||
| 230 | + __VEC_SCOPE__ | ||
| 231 | + { | ||
| 232 | + // x: int4, int8, hifp8, fp8_e5m2, fp8_e4m3 | ||
| 233 | + AscendC::Reg::RegTensor<xCopyDtype> vregX; | ||
| 234 | + AscendC::Reg::RegTensor<half> vregHalfX; | ||
| 235 | + AscendC::Reg::RegTensor<float> vregFloatX; | ||
| 236 | + // scales: fp32, bf16 | ||
| 237 | + AscendC::Reg::RegTensor<T1> vregS; | ||
| 238 | + AscendC::Reg::RegTensor<float> vregFloatS; | ||
| 239 | + // offset: fp32, bf16 | ||
| 240 | + AscendC::Reg::RegTensor<T2> vregO; | ||
| 241 | + AscendC::Reg::RegTensor<float> vregFloatO; | ||
| 242 | + // y: fp16, bf16 | ||
| 243 | + AscendC::Reg::RegTensor<float> vregFloatY; | ||
| 244 | + AscendC::Reg::RegTensor<U> vregY; | ||
| 245 | + | ||
| 246 | + AscendC::Reg::RegTensor<float> vregTmp1; | ||
| 247 | + AscendC::Reg::MaskReg mask; | ||
| 248 | + | ||
| 249 | + mask = AscendC::Reg::CreateMask<float>(); | ||
| 250 | + for (uint16_t j = 0; j < static_cast<uint16_t>(nRow); ++j) { | ||
| 251 | + uint32_t count = dataCount; | ||
| 252 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 253 | + mask = AscendC::Reg::UpdateMask<float>(count); | ||
| 254 | + // ld and cast for x | ||
| 255 | + if constexpr (IsSameType<T, hifloat8_t>::value) { | ||
| 256 | + // hifp8 | ||
| 257 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 258 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 259 | + AscendC::Reg::Cast< | ||
| 260 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HIFP8_TO_FP32>( | ||
| 261 | + vregFloatX, vregX, mask); | ||
| 262 | + } else if constexpr (IsSameType<T, fp8_e5m2_t>::value) { | ||
| 263 | + // fp8_e5m2 | ||
| 264 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 265 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 266 | + AscendC::Reg::Cast< | ||
| 267 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E5M2_TO_FP32>( | ||
| 268 | + vregFloatX, vregX, mask); | ||
| 269 | + } else if constexpr (IsSameType<T, fp8_e4m3fn_t>::value) { | ||
| 270 | + // fp8_e4m3 | ||
| 271 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 272 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 273 | + AscendC::Reg::Cast< | ||
| 274 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E4M3_TO_FP32>( | ||
| 275 | + vregFloatX, vregX, mask); | ||
| 276 | + } else if constexpr (IsSameType<T, int8_t>::value) { | ||
| 277 | + // int8 | ||
| 278 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 279 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 280 | + AscendC::Reg::Cast< | ||
| 281 | + half, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 282 | + vregHalfX, vregX, mask); | ||
| 283 | + AscendC::Reg::Cast< | ||
| 284 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 285 | + vregFloatX, vregHalfX, mask); | ||
| 286 | + } else if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 287 | + // int4 | ||
| 288 | + AscendC::Reg::RegTensor<half> vregTmpX; | ||
| 289 | + AscendC::Reg::RegTensor<uint16_t> vregTmpU16X; | ||
| 290 | + AscendC::Reg::DataCopy<xCopyDtype, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 291 | + vregX, xLocalAddr + i * HalfVL + j * xLocalOffset); | ||
| 292 | + AscendC::Reg::Cast< | ||
| 293 | + half, int4x2_t, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 294 | + (AscendC::Reg::RegTensor<half>&)vregTmpU16X, | ||
| 295 | + (AscendC::Reg::RegTensor<int4x2_t>&)vregX, mask); | ||
| 296 | + AscendC::Reg::UnPack((AscendC::Reg::RegTensor<uint32_t>&)vregTmpX, vregTmpU16X); | ||
| 297 | + AscendC::Reg::Cast< | ||
| 298 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 299 | + vregFloatX, vregTmpX, mask); | ||
| 300 | + } | ||
| 301 | + | ||
| 302 | + // ld and cast for scale | ||
| 303 | + if constexpr (IsSameType<T1, float>::value) { | ||
| 304 | + // fp32 | ||
| 305 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_NORM>( | ||
| 306 | + vregFloatS, scaleLocalAddr + i * VL); | ||
| 307 | + } else if constexpr (IsSameType<T1, bfloat16_t>::value) { | ||
| 308 | + // bf16 | ||
| 309 | + AscendC::Reg::DataCopy<T1, AscendC::Reg::LoadDist::DIST_UNPACK_B16>(vregS, scaleLocalAddr + i * VL); | ||
| 310 | + AscendC::Reg::Cast< | ||
| 311 | + float, T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 312 | + vregFloatS, vregS, mask); | ||
| 313 | + } | ||
| 314 | + | ||
| 315 | + // ld and cast for offset | ||
| 316 | + if constexpr (IsSameType<T2, float>::value) { | ||
| 317 | + // fp32 | ||
| 318 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_NORM>( | ||
| 319 | + vregFloatO, offsetLocalAddr + i * VL); | ||
| 320 | + } else if constexpr (IsSameType<T2, bfloat16_t>::value) { | ||
| 321 | + // bf16 | ||
| 322 | + AscendC::Reg::DataCopy<T2, AscendC::Reg::LoadDist::DIST_UNPACK_B16>(vregO, offsetLocalAddr + i * VL); | ||
| 323 | + AscendC::Reg::Cast< | ||
| 324 | + float, T2, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 325 | + vregFloatO, vregO, mask); | ||
| 326 | + } | ||
| 327 | + | ||
| 328 | + // compute | ||
| 329 | + AscendC::Reg::Add<float, AscendC::Reg::MaskMergeMode::ZEROING>(vregTmp1, vregFloatX, vregFloatO, mask); | ||
| 330 | + if constexpr (SqrtMode == TPL_SQRT_MODE) { | ||
| 331 | + AscendC::Reg::Mul(vregFloatS, vregFloatS, vregFloatS, mask); | ||
| 332 | + } | ||
| 333 | + AscendC::Reg::Mul(vregFloatY, vregTmp1, vregFloatS, mask); | ||
| 334 | + | ||
| 335 | + // cast and sd for y | ||
| 336 | + if constexpr (IsSameType<U, half>::value) { | ||
| 337 | + // fp16 | ||
| 338 | + AscendC::Reg::Cast< | ||
| 339 | + half, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_HALF>( | ||
| 340 | + vregY, vregFloatY, mask); | ||
| 341 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 342 | + outLocalAddr + i * VL + j * xLocalOffset, vregY, mask); | ||
| 343 | + } else if constexpr (IsSameType<U, bfloat16_t>::value) { | ||
| 344 | + // bf16 | ||
| 345 | + AscendC::Reg::Cast< | ||
| 346 | + U, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_BF16>( | ||
| 347 | + vregY, vregFloatY, mask); | ||
| 348 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 349 | + outLocalAddr + i * VL + j * xLocalOffset, vregY, mask); | ||
| 350 | + } | ||
| 351 | + } | ||
| 352 | + } | ||
| 353 | + } | ||
| 354 | + inQueueX_.FreeTensor(xLocal); | ||
| 355 | + outQueueY_.EnQue(outLocal); | ||
| 356 | +} | ||
| 357 | + | ||
| 358 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 359 | +__aicore__ inline void AscendAntiQuantV2PerChannelRegbase<T, T1, T2, U, SqrtMode>::CopyOutY( | ||
| 360 | + int64_t yN, int64_t yLen, int64_t yOutOffset) | ||
| 361 | +{ | ||
| 362 | + LocalTensor<U> outLocal = outQueueY_.DeQue<U>(); | ||
| 363 | + DataCopyExtParams copyParams; | ||
| 364 | + this->GetOutCopyParams(tilingData_->dim1, tilingData_->baseLen, yN, yLen, copyParams); | ||
| 365 | + DataCopyPad<U>(yGm_[yOutOffset], outLocal, copyParams); | ||
| 366 | + outQueueY_.FreeTensor(outLocal); | ||
| 367 | +} | ||
| 368 | +} // namespace AscendAntiQuantV2 | ||
| 369 | + | ||
Aquant/ascend_anti_quant_v2/op_kernel/arch35/ascend_anti_quant_v2_per_head_nddma_no_offset_regbase.h+372-0
| @@ -0,0 +1,372 @@ | |||
| 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 ascend_anti_quant_v2_per_head_nddma_regbase.h | ||
| 13 | + * \brief ascendantiquantv2 kernel | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +namespace AscendAntiQuantV2 { | ||
| 26 | +using namespace AscendC; | ||
| 27 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 28 | +class AscendAntiQuantV2PerHeadNddmaNoOffsetRegbase : public AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode> { | ||
| 29 | +public: | ||
| 30 | + __aicore__ inline AscendAntiQuantV2PerHeadNddmaNoOffsetRegbase(const AscendAntiQuantV2TilingData* tilingData) | ||
| 31 | + : tilingData_(tilingData){}; | ||
| 32 | + __aicore__ inline void Init(GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y); | ||
| 33 | + __aicore__ inline void Process(); | ||
| 34 | + | ||
| 35 | +private: | ||
| 36 | + using xCopyDtype = std::conditional_t<IsSameType<T, int4b_t>::value, uint8_t, T>; | ||
| 37 | + TPipe pipe_; | ||
| 38 | + constexpr static int32_t bufferNum = 2; | ||
| 39 | + TQue<QuePosition::VECIN, bufferNum> inQueueX_; | ||
| 40 | + TQue<QuePosition::VECIN, bufferNum> inQueueScale_; | ||
| 41 | + TQue<QuePosition::VECOUT, bufferNum> outQueueY_; | ||
| 42 | + GlobalTensor<uint8_t> xGm_; | ||
| 43 | + GlobalTensor<T1> scaleGm_; | ||
| 44 | + GlobalTensor<U> yGm_; | ||
| 45 | + | ||
| 46 | + const AscendAntiQuantV2TilingData* tilingData_; | ||
| 47 | + int32_t blockIdx_ = 0; | ||
| 48 | + int64_t gmXOffset_ = 0; | ||
| 49 | + int64_t gmSOffset_ = 0; | ||
| 50 | + int64_t blockN_ = 1; | ||
| 51 | + int64_t blockLen_ = 1; | ||
| 52 | + int64_t blockS_ = 1; | ||
| 53 | + int64_t nLoopLen = 0; | ||
| 54 | + int64_t nLoopNum = 0; | ||
| 55 | + int64_t nLoopTail = 0; | ||
| 56 | + int64_t loopLen = 0; | ||
| 57 | + int64_t lenLoopNum = 0; | ||
| 58 | + int64_t lenLoopTail = 0; | ||
| 59 | + | ||
| 60 | +private: | ||
| 61 | + __aicore__ inline void ProcessInputLoop(int64_t nLoopLen, int64_t baseXOffset, LocalTensor<T1>& scaleLocal); | ||
| 62 | + __aicore__ inline void CopyInParam( | ||
| 63 | + TQue<QuePosition::VECIN, bufferNum>& inQueue, GlobalTensor<T1>& inGm, int64_t paramLen, int64_t paramOffset); | ||
| 64 | + __aicore__ inline void ParseCoreBlocks(const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockS, int64_t& blockLen); | ||
| 65 | + __aicore__ inline void ProcessParamOneLoop(int64_t nLoopLen, int64_t baseSOffset, int64_t baseXOffset); | ||
| 66 | + __aicore__ inline void CopyInX(int64_t xN, int64_t xLen, int64_t xInOffset); | ||
| 67 | + __aicore__ inline void CopyOutY(int64_t yN, int64_t yLen, int64_t yOutOffset); | ||
| 68 | + __aicore__ inline void Compute(int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal); | ||
| 69 | +}; | ||
| 70 | + | ||
| 71 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 72 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Init( | ||
| 73 | + GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y) | ||
| 74 | +{ | ||
| 75 | + blockIdx_ = GetBlockIdx(); | ||
| 76 | + xGm_.SetGlobalBuffer(reinterpret_cast<__gm__ uint8_t*>(x)); | ||
| 77 | + scaleGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T1*>(scale)); | ||
| 78 | + yGm_.SetGlobalBuffer(reinterpret_cast<__gm__ U*>(y)); | ||
| 79 | + | ||
| 80 | + ParseCoreBlocks(tilingData_, blockIdx_, blockN_, blockS_, blockLen_); | ||
| 81 | + | ||
| 82 | + // calc n size to alloc queue | ||
| 83 | + pipe_.InitBuffer( | ||
| 84 | + inQueueX_, bufferNum, this->CeilAlign(tilingData_->baseN * tilingData_->baseLen * sizeof(xCopyDtype), this->BLOCK_SIZE)); | ||
| 85 | + pipe_.InitBuffer( | ||
| 86 | + inQueueScale_, bufferNum, | ||
| 87 | + this->CeilAlign(tilingData_->baseN * tilingData_->baseLen * sizeof(T1), this->BLOCK_SIZE)); | ||
| 88 | + | ||
| 89 | + pipe_.InitBuffer( | ||
| 90 | + outQueueY_, bufferNum, this->CeilAlign(tilingData_->baseN * tilingData_->baseLen * sizeof(U), this->BLOCK_SIZE)); | ||
| 91 | +} | ||
| 92 | + | ||
| 93 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 94 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Process() | ||
| 95 | +{ | ||
| 96 | + if (blockIdx_ >= tilingData_->numCore || blockN_ == 0) { | ||
| 97 | + return; | ||
| 98 | + } | ||
| 99 | + if (tilingData_->blockAxis == 0) { | ||
| 100 | + // only split axis 0 | ||
| 101 | + gmXOffset_ = blockIdx_ * tilingData_->blockFactor * tilingData_->dim1 * tilingData_->dim2; | ||
| 102 | + gmSOffset_ = 0; | ||
| 103 | + } else { | ||
| 104 | + // only split axis 1, blockUnion means factor per block on split axis | ||
| 105 | + gmXOffset_ = blockIdx_ / tilingData_->blockUnion * tilingData_->dim1 * tilingData_->dim2 + | ||
| 106 | + blockIdx_ % tilingData_->blockUnion * tilingData_->blockFactor * tilingData_->dim2; | ||
| 107 | + gmSOffset_ = blockIdx_ % tilingData_->blockUnion * tilingData_->blockFactor; | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + nLoopLen = tilingData_->baseN; | ||
| 111 | + nLoopNum = blockN_ / nLoopLen; | ||
| 112 | + nLoopTail = blockN_ % nLoopLen; | ||
| 113 | + | ||
| 114 | + loopLen = tilingData_->baseLen; | ||
| 115 | + lenLoopNum = blockLen_ / loopLen; | ||
| 116 | + lenLoopTail = blockLen_ % loopLen; | ||
| 117 | + | ||
| 118 | + for (int64_t i = 0; i < blockS_; ++i) { | ||
| 119 | + // scale allows start from begin on each core | ||
| 120 | + int64_t baseSOffset = gmSOffset_; | ||
| 121 | + int64_t baseXOffset = gmXOffset_; | ||
| 122 | + | ||
| 123 | + for (int64_t i = 0; i < nLoopNum; ++i) { | ||
| 124 | + ProcessParamOneLoop(nLoopLen, baseSOffset, baseXOffset); | ||
| 125 | + baseXOffset += nLoopLen * tilingData_->dim2; | ||
| 126 | + baseSOffset += tilingData_->baseN; | ||
| 127 | + } | ||
| 128 | + if (nLoopTail != 0) { | ||
| 129 | + ProcessParamOneLoop(nLoopTail, baseSOffset, baseXOffset); | ||
| 130 | + } | ||
| 131 | + gmXOffset_ += tilingData_->dim1 * tilingData_->dim2; | ||
| 132 | + } | ||
| 133 | +} | ||
| 134 | + | ||
| 135 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 136 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::ProcessParamOneLoop(int64_t nLoopLen, int64_t baseSOffset, int64_t baseXOffset) | ||
| 137 | +{ | ||
| 138 | + // copy in scale | ||
| 139 | + CopyInParam(inQueueScale_, scaleGm_, nLoopLen, baseSOffset % tilingData_->dim1); | ||
| 140 | + auto scaleLocal = inQueueScale_.DeQue<T1>(); | ||
| 141 | + ProcessInputLoop(nLoopLen, baseXOffset, scaleLocal); | ||
| 142 | + | ||
| 143 | + inQueueScale_.FreeTensor(scaleLocal); | ||
| 144 | +} | ||
| 145 | + | ||
| 146 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 147 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyInParam( | ||
| 148 | + TQue<QuePosition::VECIN, bufferNum>& inQueue, GlobalTensor<T1>& inGm, int64_t paramLen, | ||
| 149 | + int64_t paramOffset) | ||
| 150 | +{ | ||
| 151 | + auto paramLocal = inQueue.AllocTensor<T1>(); | ||
| 152 | + static constexpr AscendC::MultiCopyConfig copyConfig = {false, 0, 0, false}; | ||
| 153 | + MultiCopyLoopInfo<AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM> multiCopyParams; | ||
| 154 | + // src stride info per loop. | ||
| 155 | + multiCopyParams.loopSrcStride[0] = 0; | ||
| 156 | + multiCopyParams.loopSrcStride[1] = 1; | ||
| 157 | + // dst stride info per loop. | ||
| 158 | + multiCopyParams.loopDstStride[0] = 1; | ||
| 159 | + multiCopyParams.loopDstStride[1] = tilingData_->baseLen; | ||
| 160 | + // Loop size per loop. | ||
| 161 | + multiCopyParams.loopSize[0] = tilingData_->baseLen; | ||
| 162 | + multiCopyParams.loopSize[1] = paramLen; | ||
| 163 | + T1 constValue = 0; | ||
| 164 | + AscendC::MultiCopyParams<T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM> | ||
| 165 | + paramsMain = {multiCopyParams, constValue}; | ||
| 166 | + AscendC::DataCopy< | ||
| 167 | + T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM, copyConfig>( | ||
| 168 | + paramLocal, inGm[paramOffset], paramsMain); | ||
| 169 | + inQueue.EnQue(paramLocal); | ||
| 170 | +} | ||
| 171 | + | ||
| 172 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 173 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::ParseCoreBlocks( | ||
| 174 | + const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockS, int64_t& blockLen) | ||
| 175 | +{ | ||
| 176 | + if (tilingData->blockAxis == 0) { | ||
| 177 | + // blockFactor is in [1, S] | ||
| 178 | + if (blockIdx == tilingData->numCore - 1) { | ||
| 179 | + blockS = tilingData->blockTailFactor; | ||
| 180 | + } else { | ||
| 181 | + blockS = tilingData->blockFactor; | ||
| 182 | + } | ||
| 183 | + blockN = tilingData->dim1; | ||
| 184 | + blockLen = tilingData->dim2; | ||
| 185 | + } else { | ||
| 186 | + // blockFactor is in [1, N], blockUnion is in [1, N/blockFactor] | ||
| 187 | + if (blockIdx % tilingData->blockUnion == tilingData->blockUnion - 1) { | ||
| 188 | + blockN = tilingData->blockTailFactor; | ||
| 189 | + } else { | ||
| 190 | + blockN = tilingData->blockFactor; | ||
| 191 | + } | ||
| 192 | + blockLen = tilingData->dim2; | ||
| 193 | + } | ||
| 194 | +} | ||
| 195 | + | ||
| 196 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 197 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::ProcessInputLoop( | ||
| 198 | + int64_t nLoopLen, int64_t baseXOffset, LocalTensor<T1>& scaleLocal) | ||
| 199 | +{ | ||
| 200 | + for (auto i = 0; i < lenLoopNum; ++i) { | ||
| 201 | + CopyInX(nLoopLen, loopLen, baseXOffset); | ||
| 202 | + Compute(nLoopLen, loopLen, scaleLocal); | ||
| 203 | + CopyOutY(nLoopLen, loopLen, baseXOffset); | ||
| 204 | + baseXOffset += tilingData_->baseLen; | ||
| 205 | + } | ||
| 206 | + if (lenLoopTail != 0) { | ||
| 207 | + CopyInX(nLoopLen, lenLoopTail, baseXOffset); | ||
| 208 | + Compute(nLoopLen, lenLoopTail, scaleLocal); | ||
| 209 | + CopyOutY(nLoopLen, lenLoopTail, baseXOffset); | ||
| 210 | + } | ||
| 211 | +} | ||
| 212 | + | ||
| 213 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 214 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyInX( | ||
| 215 | + int64_t xN, int64_t xLen, int64_t xInOffset) | ||
| 216 | +{ | ||
| 217 | + int64_t xLenReal = xLen; | ||
| 218 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 219 | + xInOffset = xInOffset >> 1; | ||
| 220 | + xLenReal = xLenReal >> 1; | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | + LocalTensor<uint8_t> xLocal = inQueueX_.AllocTensor<uint8_t>(); | ||
| 224 | + DataCopyExtParams copyParams; | ||
| 225 | + DataCopyPadExtParams<uint8_t> padParams = {false, 0, 0, 0}; | ||
| 226 | + copyParams.blockCount = 1; | ||
| 227 | + copyParams.blockLen = xN * xLenReal * sizeof(xCopyDtype); | ||
| 228 | + copyParams.dstStride = 0; | ||
| 229 | + copyParams.srcStride = 0; | ||
| 230 | + DataCopyPad<uint8_t>(xLocal, xGm_[xInOffset], copyParams, padParams); | ||
| 231 | + inQueueX_.EnQue(xLocal); | ||
| 232 | +} | ||
| 233 | + | ||
| 234 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 235 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Compute( | ||
| 236 | + int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal) | ||
| 237 | +{ | ||
| 238 | + LocalTensor<xCopyDtype> xLocal = inQueueX_.DeQue<xCopyDtype>(); | ||
| 239 | + LocalTensor<U> outLocal = outQueueY_.AllocTensor<U>(); | ||
| 240 | + | ||
| 241 | + __local_mem__ xCopyDtype* xLocalAddr = (__local_mem__ xCopyDtype*)xLocal.GetPhyAddr(); | ||
| 242 | + __local_mem__ T1* scaleLocalAddr = (__local_mem__ T1*)sLocal.GetPhyAddr(); | ||
| 243 | + __local_mem__ U* outLocalAddr = (__local_mem__ U*)outLocal.GetPhyAddr(); | ||
| 244 | + | ||
| 245 | + uint16_t VL = AscendC::VECTOR_REG_WIDTH / sizeof(float); | ||
| 246 | + uint16_t HalfVL = VL / 2; | ||
| 247 | + | ||
| 248 | + // has offset | ||
| 249 | + __VEC_SCOPE__ | ||
| 250 | + { | ||
| 251 | + // x: int4, int8, hifp8, fp8_e5m2, fp8_e4m3 | ||
| 252 | + AscendC::Reg::RegTensor<xCopyDtype> vregX; | ||
| 253 | + AscendC::Reg::RegTensor<half> vregHalfX; | ||
| 254 | + AscendC::Reg::RegTensor<float> vregFloatX; | ||
| 255 | + // scales: fp32, bf16 | ||
| 256 | + AscendC::Reg::RegTensor<T1> vregS; | ||
| 257 | + AscendC::Reg::RegTensor<float> vregFloatS; | ||
| 258 | + // y: fp16, bf16 | ||
| 259 | + AscendC::Reg::RegTensor<float> vregFloatY; | ||
| 260 | + AscendC::Reg::RegTensor<U> vregY; | ||
| 261 | + | ||
| 262 | + AscendC::Reg::MaskReg mask; | ||
| 263 | + | ||
| 264 | + mask = AscendC::Reg::CreateMask<float>(); | ||
| 265 | + uint32_t count = dataCount * nRow; | ||
| 266 | + uint16_t vfLoopNum = (count + VL - 1) / VL; | ||
| 267 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 268 | + mask = AscendC::Reg::UpdateMask<float>(count); | ||
| 269 | + // ld and cast for x | ||
| 270 | + if constexpr (IsSameType<T, hifloat8_t>::value) { | ||
| 271 | + // hifp8 | ||
| 272 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 273 | + vregX, xLocalAddr + i * VL); | ||
| 274 | + AscendC::Reg::Cast< | ||
| 275 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HIFP8_TO_FP32>( | ||
| 276 | + vregFloatX, vregX, mask); | ||
| 277 | + } else if constexpr (IsSameType<T, fp8_e5m2_t>::value) { | ||
| 278 | + // fp8_e5m2 | ||
| 279 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 280 | + vregX, xLocalAddr + i * VL); | ||
| 281 | + AscendC::Reg::Cast< | ||
| 282 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E5M2_TO_FP32>( | ||
| 283 | + vregFloatX, vregX, mask); | ||
| 284 | + } else if constexpr (IsSameType<T, fp8_e4m3fn_t>::value) { | ||
| 285 | + // fp8_e4m3 | ||
| 286 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 287 | + vregX, xLocalAddr + i * VL); | ||
| 288 | + AscendC::Reg::Cast< | ||
| 289 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E4M3_TO_FP32>( | ||
| 290 | + vregFloatX, vregX, mask); | ||
| 291 | + } else if constexpr (IsSameType<T, int8_t>::value) { | ||
| 292 | + // int8 | ||
| 293 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 294 | + vregX, xLocalAddr + i * VL); | ||
| 295 | + AscendC::Reg::Cast< | ||
| 296 | + half, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 297 | + vregHalfX, vregX, mask); | ||
| 298 | + AscendC::Reg::Cast< | ||
| 299 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 300 | + vregFloatX, vregHalfX, mask); | ||
| 301 | + } else if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 302 | + // int4 | ||
| 303 | + AscendC::Reg::RegTensor<half> vregTmpX; | ||
| 304 | + AscendC::Reg::RegTensor<uint16_t> vregTmpU16X; | ||
| 305 | + AscendC::Reg::DataCopy<xCopyDtype, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 306 | + vregX, xLocalAddr + i * HalfVL); | ||
| 307 | + AscendC::Reg::Cast< | ||
| 308 | + half, int4x2_t, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 309 | + (AscendC::Reg::RegTensor<half>&)vregTmpU16X, | ||
| 310 | + (AscendC::Reg::RegTensor<int4x2_t>&)vregX, mask); | ||
| 311 | + AscendC::Reg::UnPack((AscendC::Reg::RegTensor<uint32_t>&)vregTmpX, vregTmpU16X); | ||
| 312 | + AscendC::Reg::Cast< | ||
| 313 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 314 | + vregFloatX, vregTmpX, mask); | ||
| 315 | + } | ||
| 316 | + | ||
| 317 | + // ld and cast for scale | ||
| 318 | + if constexpr (IsSameType<T1, float>::value) { | ||
| 319 | + // fp32 | ||
| 320 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_NORM>( | ||
| 321 | + vregFloatS, scaleLocalAddr + i * VL); | ||
| 322 | + } else if constexpr (IsSameType<T1, bfloat16_t>::value) { | ||
| 323 | + // bf16 | ||
| 324 | + AscendC::Reg::DataCopy<T1, AscendC::Reg::LoadDist::DIST_UNPACK_B16>(vregS, scaleLocalAddr + i * VL); | ||
| 325 | + AscendC::Reg::Cast< | ||
| 326 | + float, T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 327 | + vregFloatS, vregS, mask); | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | + // compute | ||
| 331 | + if constexpr (SqrtMode == TPL_SQRT_MODE) { | ||
| 332 | + AscendC::Reg::Mul(vregFloatS, vregFloatS, vregFloatS, mask); | ||
| 333 | + } | ||
| 334 | + AscendC::Reg::Mul(vregFloatY, vregFloatX, vregFloatS, mask); | ||
| 335 | + | ||
| 336 | + // cast and sd for y | ||
| 337 | + if constexpr (IsSameType<U, half>::value) { | ||
| 338 | + // fp16 | ||
| 339 | + AscendC::Reg::Cast< | ||
| 340 | + half, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_HALF>( | ||
| 341 | + vregY, vregFloatY, mask); | ||
| 342 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 343 | + outLocalAddr + i * VL, vregY, mask); | ||
| 344 | + } else if constexpr (IsSameType<U, bfloat16_t>::value) { | ||
| 345 | + // bf16 | ||
| 346 | + AscendC::Reg::Cast< | ||
| 347 | + U, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_BF16>( | ||
| 348 | + vregY, vregFloatY, mask); | ||
| 349 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 350 | + outLocalAddr + i * VL, vregY, mask); | ||
| 351 | + } | ||
| 352 | + } | ||
| 353 | + } | ||
| 354 | + inQueueX_.FreeTensor(xLocal); | ||
| 355 | + outQueueY_.EnQue(outLocal); | ||
| 356 | +} | ||
| 357 | + | ||
| 358 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 359 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyOutY( | ||
| 360 | + int64_t yN, int64_t yLen, int64_t yOutOffset) | ||
| 361 | +{ | ||
| 362 | + LocalTensor<U> outLocal = outQueueY_.DeQue<U>(); | ||
| 363 | + DataCopyExtParams copyParams; | ||
| 364 | + copyParams.blockCount = 1; | ||
| 365 | + copyParams.blockLen = yN * yLen * sizeof(U); | ||
| 366 | + copyParams.dstStride = 0; | ||
| 367 | + copyParams.srcStride = 0; | ||
| 368 | + DataCopyPad<U>(yGm_[yOutOffset], outLocal, copyParams); | ||
| 369 | + outQueueY_.FreeTensor(outLocal); | ||
| 370 | +} | ||
| 371 | +} // namespace AscendAntiQuantV2 | ||
| 372 | + | ||
| @@ -0,0 +1,403 @@ | |||
| 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 ascend_anti_quant_v2_per_head_nddma_regbase.h | ||
| 13 | + * \brief ascendantiquantv2 kernel | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +namespace AscendAntiQuantV2 { | ||
| 26 | +using namespace AscendC; | ||
| 27 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 28 | +class AscendAntiQuantV2PerHeadNddmaRegbase : public AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode> { | ||
| 29 | +public: | ||
| 30 | + __aicore__ inline AscendAntiQuantV2PerHeadNddmaRegbase(const AscendAntiQuantV2TilingData* tilingData) | ||
| 31 | + : tilingData_(tilingData){}; | ||
| 32 | + __aicore__ inline void Init(GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y); | ||
| 33 | + __aicore__ inline void Process(); | ||
| 34 | + | ||
| 35 | +private: | ||
| 36 | + using xCopyDtype = std::conditional_t<IsSameType<T, int4b_t>::value, uint8_t, T>; | ||
| 37 | + TPipe pipe_; | ||
| 38 | + constexpr static int32_t bufferNum = 2; | ||
| 39 | + TQue<QuePosition::VECIN, bufferNum> inQueueX_; | ||
| 40 | + TQue<QuePosition::VECIN, bufferNum> inQueueScale_; | ||
| 41 | + TQue<QuePosition::VECIN, bufferNum> inQueueOffset_; | ||
| 42 | + TQue<QuePosition::VECOUT, bufferNum> outQueueY_; | ||
| 43 | + GlobalTensor<uint8_t> xGm_; | ||
| 44 | + GlobalTensor<T1> scaleGm_; | ||
| 45 | + GlobalTensor<T2> offsetGm_; | ||
| 46 | + GlobalTensor<U> yGm_; | ||
| 47 | + | ||
| 48 | + const AscendAntiQuantV2TilingData* tilingData_; | ||
| 49 | + int32_t blockIdx_ = 0; | ||
| 50 | + int64_t gmXOffset_ = 0; | ||
| 51 | + int64_t gmSOffset_ = 0; | ||
| 52 | + int64_t blockN_ = 1; | ||
| 53 | + int64_t blockLen_ = 1; | ||
| 54 | + int64_t blockS_ = 1; | ||
| 55 | + int64_t nLoopLen = 0; | ||
| 56 | + int64_t nLoopNum = 0; | ||
| 57 | + int64_t nLoopTail = 0; | ||
| 58 | + int64_t loopLen = 0; | ||
| 59 | + int64_t lenLoopNum = 0; | ||
| 60 | + int64_t lenLoopTail = 0; | ||
| 61 | + | ||
| 62 | +private: | ||
| 63 | + __aicore__ inline void ProcessInputLoop( | ||
| 64 | + int64_t nLoopLen, int64_t baseXOffset, LocalTensor<T1>& scaleLocal, LocalTensor<T2>& offsetLocal); | ||
| 65 | + template <typename dtypeCopyIn> | ||
| 66 | + __aicore__ inline void CopyInParam( | ||
| 67 | + TQue<QuePosition::VECIN, bufferNum>& inQueue, GlobalTensor<dtypeCopyIn>& inGm, int64_t paramLen, int64_t paramOffset); | ||
| 68 | + __aicore__ inline void ParseCoreBlocks(const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockS, int64_t& blockLen); | ||
| 69 | + __aicore__ inline void ProcessParamOneLoop(int64_t nLoopLen, int64_t baseSOffset, int64_t baseXOffset); | ||
| 70 | + __aicore__ inline void CopyInX(int64_t xN, int64_t xLen, int64_t xInOffset); | ||
| 71 | + __aicore__ inline void CopyOutY(int64_t yN, int64_t yLen, int64_t yOutOffset); | ||
| 72 | + __aicore__ inline void Compute(int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal); | ||
| 73 | +}; | ||
| 74 | + | ||
| 75 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 76 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaRegbase<T, T1, T2, U, SqrtMode>::Init( | ||
| 77 | + GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y) | ||
| 78 | +{ | ||
| 79 | + blockIdx_ = GetBlockIdx(); | ||
| 80 | + xGm_.SetGlobalBuffer(reinterpret_cast<__gm__ uint8_t*>(x)); | ||
| 81 | + scaleGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T1*>(scale)); | ||
| 82 | + offsetGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T2*>(offset)); | ||
| 83 | + yGm_.SetGlobalBuffer(reinterpret_cast<__gm__ U*>(y)); | ||
| 84 | + | ||
| 85 | + ParseCoreBlocks(tilingData_, blockIdx_, blockN_, blockS_, blockLen_); | ||
| 86 | + | ||
| 87 | + // calc n size to alloc queue | ||
| 88 | + pipe_.InitBuffer( | ||
| 89 | + inQueueX_, bufferNum, this->CeilAlign(tilingData_->baseN * tilingData_->baseLen * sizeof(xCopyDtype), this->BLOCK_SIZE)); | ||
| 90 | + pipe_.InitBuffer( | ||
| 91 | + inQueueScale_, bufferNum, | ||
| 92 | + this->CeilAlign(tilingData_->baseN * tilingData_->baseLen * sizeof(T1), this->BLOCK_SIZE)); | ||
| 93 | + pipe_.InitBuffer( | ||
| 94 | + inQueueOffset_, bufferNum, | ||
| 95 | + this->CeilAlign(tilingData_->baseN * tilingData_->baseLen * sizeof(T2), this->BLOCK_SIZE)); | ||
| 96 | + | ||
| 97 | + pipe_.InitBuffer( | ||
| 98 | + outQueueY_, bufferNum, this->CeilAlign(tilingData_->baseN * tilingData_->baseLen * sizeof(U), this->BLOCK_SIZE)); | ||
| 99 | +} | ||
| 100 | + | ||
| 101 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 102 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaRegbase<T, T1, T2, U, SqrtMode>::Process() | ||
| 103 | +{ | ||
| 104 | + if (blockIdx_ >= tilingData_->numCore || blockN_ == 0) { | ||
| 105 | + return; | ||
| 106 | + } | ||
| 107 | + if (tilingData_->blockAxis == 0) { | ||
| 108 | + // only split axis 0 | ||
| 109 | + gmXOffset_ = blockIdx_ * tilingData_->blockFactor * tilingData_->dim1 * tilingData_->dim2; | ||
| 110 | + gmSOffset_ = 0; | ||
| 111 | + } else { | ||
| 112 | + // only split axis 1, blockUnion means factor per block on split axis | ||
| 113 | + gmXOffset_ = blockIdx_ / tilingData_->blockUnion * tilingData_->dim1 * tilingData_->dim2 + | ||
| 114 | + blockIdx_ % tilingData_->blockUnion * tilingData_->blockFactor * tilingData_->dim2; | ||
| 115 | + gmSOffset_ = blockIdx_ % tilingData_->blockUnion * tilingData_->blockFactor; | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + nLoopLen = tilingData_->baseN; | ||
| 119 | + nLoopNum = blockN_ / nLoopLen; | ||
| 120 | + nLoopTail = blockN_ % nLoopLen; | ||
| 121 | + | ||
| 122 | + loopLen = tilingData_->baseLen; | ||
| 123 | + lenLoopNum = blockLen_ / loopLen; | ||
| 124 | + lenLoopTail = blockLen_ % loopLen; | ||
| 125 | + | ||
| 126 | + for (int64_t i = 0; i < blockS_; ++i) { | ||
| 127 | + // scale allows start from begin on each core | ||
| 128 | + int64_t baseSOffset = gmSOffset_; | ||
| 129 | + int64_t baseXOffset = gmXOffset_; | ||
| 130 | + | ||
| 131 | + for (int64_t i = 0; i < nLoopNum; ++i) { | ||
| 132 | + ProcessParamOneLoop(nLoopLen, baseSOffset, baseXOffset); | ||
| 133 | + baseXOffset += nLoopLen * tilingData_->dim2; | ||
| 134 | + baseSOffset += tilingData_->baseN; | ||
| 135 | + } | ||
| 136 | + if (nLoopTail != 0) { | ||
| 137 | + ProcessParamOneLoop(nLoopTail, baseSOffset, baseXOffset); | ||
| 138 | + } | ||
| 139 | + gmXOffset_ += tilingData_->dim1 * tilingData_->dim2; | ||
| 140 | + } | ||
| 141 | +} | ||
| 142 | + | ||
| 143 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 144 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaRegbase<T, T1, T2, U, SqrtMode>::ProcessParamOneLoop(int64_t nLoopLen, int64_t baseSOffset, int64_t baseXOffset) | ||
| 145 | +{ | ||
| 146 | + // copy in scale and offset | ||
| 147 | + CopyInParam<T1>(inQueueScale_, scaleGm_, nLoopLen, baseSOffset % tilingData_->dim1); | ||
| 148 | + auto scaleLocal = inQueueScale_.DeQue<T1>(); | ||
| 149 | + CopyInParam<T2>(inQueueOffset_, offsetGm_, nLoopLen, baseSOffset % tilingData_->dim1); | ||
| 150 | + auto offsetLocal = inQueueOffset_.DeQue<T2>(); | ||
| 151 | + ProcessInputLoop(nLoopLen, baseXOffset, scaleLocal, offsetLocal); | ||
| 152 | + inQueueOffset_.FreeTensor(offsetLocal); | ||
| 153 | + | ||
| 154 | + inQueueScale_.FreeTensor(scaleLocal); | ||
| 155 | +} | ||
| 156 | + | ||
| 157 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 158 | +template <typename dtypeCopyIn> | ||
| 159 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaRegbase<T, T1, T2, U, SqrtMode>::CopyInParam( | ||
| 160 | + TQue<QuePosition::VECIN, bufferNum>& inQueue, GlobalTensor<dtypeCopyIn>& inGm, int64_t paramLen, | ||
| 161 | + int64_t paramOffset) | ||
| 162 | +{ | ||
| 163 | + auto paramLocal = inQueue.AllocTensor<dtypeCopyIn>(); | ||
| 164 | + static constexpr AscendC::MultiCopyConfig copyConfig = {false, 0, 0, false}; | ||
| 165 | + MultiCopyLoopInfo<AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM> multiCopyParams; | ||
| 166 | + // src stride info per loop. | ||
| 167 | + multiCopyParams.loopSrcStride[0] = 0; | ||
| 168 | + multiCopyParams.loopSrcStride[1] = 1; | ||
| 169 | + // dst stride info per loop. | ||
| 170 | + multiCopyParams.loopDstStride[0] = 1; | ||
| 171 | + multiCopyParams.loopDstStride[1] = tilingData_->baseLen; | ||
| 172 | + // Loop size per loop. | ||
| 173 | + multiCopyParams.loopSize[0] = tilingData_->baseLen; | ||
| 174 | + multiCopyParams.loopSize[1] = paramLen; | ||
| 175 | + dtypeCopyIn constValue = 0; | ||
| 176 | + AscendC::MultiCopyParams<dtypeCopyIn, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM> | ||
| 177 | + paramsMain = {multiCopyParams, constValue}; | ||
| 178 | + AscendC::DataCopy< | ||
| 179 | + dtypeCopyIn, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::MULTI_COPY_DIM, copyConfig>( | ||
| 180 | + paramLocal, inGm[paramOffset], paramsMain); | ||
| 181 | + inQueue.EnQue(paramLocal); | ||
| 182 | +} | ||
| 183 | + | ||
| 184 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 185 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaRegbase<T, T1, T2, U, SqrtMode>::ParseCoreBlocks( | ||
| 186 | + const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockS, int64_t& blockLen) | ||
| 187 | +{ | ||
| 188 | + if (tilingData->blockAxis == 0) { | ||
| 189 | + // blockFactor is in [1, S] | ||
| 190 | + if (blockIdx == tilingData->numCore - 1) { | ||
| 191 | + blockS = tilingData->blockTailFactor; | ||
| 192 | + } else { | ||
| 193 | + blockS = tilingData->blockFactor; | ||
| 194 | + } | ||
| 195 | + blockN = tilingData->dim1; | ||
| 196 | + blockLen = tilingData->dim2; | ||
| 197 | + } else { | ||
| 198 | + // blockFactor is in [1, N], blockUnion is in [1, N/blockFactor] | ||
| 199 | + if (blockIdx % tilingData->blockUnion == tilingData->blockUnion - 1) { | ||
| 200 | + blockN = tilingData->blockTailFactor; | ||
| 201 | + } else { | ||
| 202 | + blockN = tilingData->blockFactor; | ||
| 203 | + } | ||
| 204 | + blockLen = tilingData->dim2; | ||
| 205 | + } | ||
| 206 | +} | ||
| 207 | + | ||
| 208 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 209 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaRegbase<T, T1, T2, U, SqrtMode>::ProcessInputLoop( | ||
| 210 | + int64_t nLoopLen, int64_t baseXOffset, LocalTensor<T1>& scaleLocal, LocalTensor<T2>& offsetLocal) | ||
| 211 | +{ | ||
| 212 | + for (auto i = 0; i < lenLoopNum; ++i) { | ||
| 213 | + CopyInX(nLoopLen, loopLen, baseXOffset); | ||
| 214 | + Compute(nLoopLen, loopLen, scaleLocal, offsetLocal); | ||
| 215 | + CopyOutY(nLoopLen, loopLen, baseXOffset); | ||
| 216 | + baseXOffset += tilingData_->baseLen; | ||
| 217 | + } | ||
| 218 | + if (lenLoopTail != 0) { | ||
| 219 | + CopyInX(nLoopLen, lenLoopTail, baseXOffset); | ||
| 220 | + Compute(nLoopLen, lenLoopTail, scaleLocal, offsetLocal); | ||
| 221 | + CopyOutY(nLoopLen, lenLoopTail, baseXOffset); | ||
| 222 | + } | ||
| 223 | +} | ||
| 224 | + | ||
| 225 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 226 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaRegbase<T, T1, T2, U, SqrtMode>::CopyInX( | ||
| 227 | + int64_t xN, int64_t xLen, int64_t xInOffset) | ||
| 228 | +{ | ||
| 229 | + int64_t xLenReal = xLen; | ||
| 230 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 231 | + xInOffset = xInOffset >> 1; | ||
| 232 | + xLenReal = xLenReal >> 1; | ||
| 233 | + } | ||
| 234 | + | ||
| 235 | + LocalTensor<uint8_t> xLocal = inQueueX_.AllocTensor<uint8_t>(); | ||
| 236 | + DataCopyExtParams copyParams; | ||
| 237 | + DataCopyPadExtParams<uint8_t> padParams = {false, 0, 0, 0}; | ||
| 238 | + copyParams.blockCount = 1; | ||
| 239 | + copyParams.blockLen = xN * xLenReal * sizeof(xCopyDtype); | ||
| 240 | + copyParams.dstStride = 0; | ||
| 241 | + copyParams.srcStride = 0; | ||
| 242 | + DataCopyPad<uint8_t>(xLocal, xGm_[xInOffset], copyParams, padParams); | ||
| 243 | + inQueueX_.EnQue(xLocal); | ||
| 244 | +} | ||
| 245 | + | ||
| 246 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 247 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaRegbase<T, T1, T2, U, SqrtMode>::Compute( | ||
| 248 | + int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal) | ||
| 249 | +{ | ||
| 250 | + LocalTensor<xCopyDtype> xLocal = inQueueX_.DeQue<xCopyDtype>(); | ||
| 251 | + LocalTensor<U> outLocal = outQueueY_.AllocTensor<U>(); | ||
| 252 | + | ||
| 253 | + __local_mem__ xCopyDtype* xLocalAddr = (__local_mem__ xCopyDtype*)xLocal.GetPhyAddr(); | ||
| 254 | + __local_mem__ T1* scaleLocalAddr = (__local_mem__ T1*)sLocal.GetPhyAddr(); | ||
| 255 | + __local_mem__ T2* offsetLocalAddr = (__local_mem__ T2*)oLocal.GetPhyAddr(); | ||
| 256 | + __local_mem__ U* outLocalAddr = (__local_mem__ U*)outLocal.GetPhyAddr(); | ||
| 257 | + | ||
| 258 | + uint16_t VL = AscendC::VECTOR_REG_WIDTH / sizeof(float); | ||
| 259 | + uint16_t HalfVL = VL / 2; | ||
| 260 | + | ||
| 261 | + // has offset | ||
| 262 | + __VEC_SCOPE__ | ||
| 263 | + { | ||
| 264 | + // x: int4, int8, hifp8, fp8_e5m2, fp8_e4m3 | ||
| 265 | + AscendC::Reg::RegTensor<xCopyDtype> vregX; | ||
| 266 | + AscendC::Reg::RegTensor<half> vregHalfX; | ||
| 267 | + AscendC::Reg::RegTensor<float> vregFloatX; | ||
| 268 | + // scales: fp32, bf16 | ||
| 269 | + AscendC::Reg::RegTensor<T1> vregS; | ||
| 270 | + AscendC::Reg::RegTensor<float> vregFloatS; | ||
| 271 | + // offset: fp32, bf16 | ||
| 272 | + AscendC::Reg::RegTensor<T2> vregO; | ||
| 273 | + AscendC::Reg::RegTensor<float> vregFloatO; | ||
| 274 | + // y: fp16, bf16 | ||
| 275 | + AscendC::Reg::RegTensor<float> vregFloatY; | ||
| 276 | + AscendC::Reg::RegTensor<U> vregY; | ||
| 277 | + | ||
| 278 | + AscendC::Reg::RegTensor<float> vregTmp1; | ||
| 279 | + AscendC::Reg::MaskReg mask; | ||
| 280 | + | ||
| 281 | + mask = AscendC::Reg::CreateMask<float>(); | ||
| 282 | + uint32_t count = dataCount * nRow; | ||
| 283 | + uint16_t vfLoopNum = (count + VL - 1) / VL; | ||
| 284 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 285 | + mask = AscendC::Reg::UpdateMask<float>(count); | ||
| 286 | + // ld and cast for x | ||
| 287 | + if constexpr (IsSameType<T, hifloat8_t>::value) { | ||
| 288 | + // hifp8 | ||
| 289 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 290 | + vregX, xLocalAddr + i * VL); | ||
| 291 | + AscendC::Reg::Cast< | ||
| 292 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HIFP8_TO_FP32>( | ||
| 293 | + vregFloatX, vregX, mask); | ||
| 294 | + } else if constexpr (IsSameType<T, fp8_e5m2_t>::value) { | ||
| 295 | + // fp8_e5m2 | ||
| 296 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 297 | + vregX, xLocalAddr + i * VL); | ||
| 298 | + AscendC::Reg::Cast< | ||
| 299 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E5M2_TO_FP32>( | ||
| 300 | + vregFloatX, vregX, mask); | ||
| 301 | + } else if constexpr (IsSameType<T, fp8_e4m3fn_t>::value) { | ||
| 302 | + // fp8_e4m3 | ||
| 303 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 304 | + vregX, xLocalAddr + i * VL); | ||
| 305 | + AscendC::Reg::Cast< | ||
| 306 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E4M3_TO_FP32>( | ||
| 307 | + vregFloatX, vregX, mask); | ||
| 308 | + } else if constexpr (IsSameType<T, int8_t>::value) { | ||
| 309 | + // int8 | ||
| 310 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 311 | + vregX, xLocalAddr + i * VL); | ||
| 312 | + AscendC::Reg::Cast< | ||
| 313 | + half, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 314 | + vregHalfX, vregX, mask); | ||
| 315 | + AscendC::Reg::Cast< | ||
| 316 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 317 | + vregFloatX, vregHalfX, mask); | ||
| 318 | + } else if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 319 | + // int4 | ||
| 320 | + AscendC::Reg::RegTensor<half> vregTmpX; | ||
| 321 | + AscendC::Reg::RegTensor<uint16_t> vregTmpU16X; | ||
| 322 | + AscendC::Reg::DataCopy<xCopyDtype, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 323 | + vregX, xLocalAddr + i * HalfVL); | ||
| 324 | + AscendC::Reg::Cast< | ||
| 325 | + half, int4x2_t, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 326 | + (AscendC::Reg::RegTensor<half>&)vregTmpU16X, | ||
| 327 | + (AscendC::Reg::RegTensor<int4x2_t>&)vregX, mask); | ||
| 328 | + AscendC::Reg::UnPack((AscendC::Reg::RegTensor<uint32_t>&)vregTmpX, vregTmpU16X); | ||
| 329 | + AscendC::Reg::Cast< | ||
| 330 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 331 | + vregFloatX, vregTmpX, mask); | ||
| 332 | + } | ||
| 333 | + | ||
| 334 | + // ld and cast for scale | ||
| 335 | + if constexpr (IsSameType<T1, float>::value) { | ||
| 336 | + // fp32 | ||
| 337 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_NORM>( | ||
| 338 | + vregFloatS, scaleLocalAddr + i * VL); | ||
| 339 | + } else if constexpr (IsSameType<T1, bfloat16_t>::value) { | ||
| 340 | + // bf16 | ||
| 341 | + AscendC::Reg::DataCopy<T1, AscendC::Reg::LoadDist::DIST_UNPACK_B16>(vregS, scaleLocalAddr + i * VL); | ||
| 342 | + AscendC::Reg::Cast< | ||
| 343 | + float, T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 344 | + vregFloatS, vregS, mask); | ||
| 345 | + } | ||
| 346 | + | ||
| 347 | + // ld and cast for offset | ||
| 348 | + if constexpr (IsSameType<T2, float>::value) { | ||
| 349 | + // fp32 | ||
| 350 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_NORM>( | ||
| 351 | + vregFloatO, offsetLocalAddr + i * VL); | ||
| 352 | + } else if constexpr (IsSameType<T2, bfloat16_t>::value) { | ||
| 353 | + // bf16 | ||
| 354 | + AscendC::Reg::DataCopy<T2, AscendC::Reg::LoadDist::DIST_UNPACK_B16>(vregO, offsetLocalAddr + i * VL); | ||
| 355 | + AscendC::Reg::Cast< | ||
| 356 | + float, T2, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 357 | + vregFloatO, vregO, mask); | ||
| 358 | + } | ||
| 359 | + | ||
| 360 | + // compute | ||
| 361 | + AscendC::Reg::Add<float, AscendC::Reg::MaskMergeMode::ZEROING>(vregTmp1, vregFloatX, vregFloatO, mask); | ||
| 362 | + if constexpr (SqrtMode == TPL_SQRT_MODE) { | ||
| 363 | + AscendC::Reg::Mul(vregFloatS, vregFloatS, vregFloatS, mask); | ||
| 364 | + } | ||
| 365 | + AscendC::Reg::Mul(vregFloatY, vregTmp1, vregFloatS, mask); | ||
| 366 | + | ||
| 367 | + // cast and sd for y | ||
| 368 | + if constexpr (IsSameType<U, half>::value) { | ||
| 369 | + // fp16 | ||
| 370 | + AscendC::Reg::Cast< | ||
| 371 | + half, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_HALF>( | ||
| 372 | + vregY, vregFloatY, mask); | ||
| 373 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 374 | + outLocalAddr + i * VL, vregY, mask); | ||
| 375 | + } else if constexpr (IsSameType<U, bfloat16_t>::value) { | ||
| 376 | + // bf16 | ||
| 377 | + AscendC::Reg::Cast< | ||
| 378 | + U, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_BF16>( | ||
| 379 | + vregY, vregFloatY, mask); | ||
| 380 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 381 | + outLocalAddr + i * VL, vregY, mask); | ||
| 382 | + } | ||
| 383 | + } | ||
| 384 | + } | ||
| 385 | + inQueueX_.FreeTensor(xLocal); | ||
| 386 | + outQueueY_.EnQue(outLocal); | ||
| 387 | +} | ||
| 388 | + | ||
| 389 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 390 | +__aicore__ inline void AscendAntiQuantV2PerHeadNddmaRegbase<T, T1, T2, U, SqrtMode>::CopyOutY( | ||
| 391 | + int64_t yN, int64_t yLen, int64_t yOutOffset) | ||
| 392 | +{ | ||
| 393 | + LocalTensor<U> outLocal = outQueueY_.DeQue<U>(); | ||
| 394 | + DataCopyExtParams copyParams; | ||
| 395 | + copyParams.blockCount = 1; | ||
| 396 | + copyParams.blockLen = yN * yLen * sizeof(U); | ||
| 397 | + copyParams.dstStride = 0; | ||
| 398 | + copyParams.srcStride = 0; | ||
| 399 | + DataCopyPad<U>(yGm_[yOutOffset], outLocal, copyParams); | ||
| 400 | + outQueueY_.FreeTensor(outLocal); | ||
| 401 | +} | ||
| 402 | +} // namespace AscendAntiQuantV2 | ||
| 403 | + | ||
Aquant/ascend_anti_quant_v2/op_kernel/arch35/ascend_anti_quant_v2_per_head_no_offset_regbase.h+418-0
| @@ -0,0 +1,418 @@ | |||
| 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 ascend_anti_quant_v2_per_head_no_offset_regbase.h | ||
| 13 | + * \brief ascendantiquantv2 kernel | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +namespace AscendAntiQuantV2 { | ||
| 26 | +using namespace AscendC; | ||
| 27 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 28 | +class AscendAntiQuantV2PerHeadNoOffsetRegbase : public AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode> { | ||
| 29 | +public: | ||
| 30 | + __aicore__ inline AscendAntiQuantV2PerHeadNoOffsetRegbase(const AscendAntiQuantV2TilingData* tilingData) | ||
| 31 | + : tilingData_(tilingData){}; | ||
| 32 | + __aicore__ inline void Init(GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y); | ||
| 33 | + __aicore__ inline void Process(); | ||
| 34 | + | ||
| 35 | +private: | ||
| 36 | + using xCopyDtype = std::conditional_t<IsSameType<T, int4b_t>::value, uint8_t, T>; | ||
| 37 | + TPipe pipe_; | ||
| 38 | + constexpr static int32_t bufferNum = 2; | ||
| 39 | + TQue<QuePosition::VECIN, bufferNum> inQueueX_; | ||
| 40 | + TQue<QuePosition::VECIN, bufferNum> inQueueScale_; | ||
| 41 | + TQue<QuePosition::VECOUT, bufferNum> outQueueY_; | ||
| 42 | + GlobalTensor<uint8_t> xGm_; | ||
| 43 | + GlobalTensor<T1> scaleGm_; | ||
| 44 | + GlobalTensor<U> yGm_; | ||
| 45 | + | ||
| 46 | + const AscendAntiQuantV2TilingData* tilingData_; | ||
| 47 | + int32_t blockIdx_ = 0; | ||
| 48 | + int64_t gmXOffset_ = 0; | ||
| 49 | + int64_t gmSOffset_ = 0; | ||
| 50 | + int64_t blockN_ = 1; | ||
| 51 | + int64_t blockLen_ = 1; | ||
| 52 | + int64_t blockS_ = 1; | ||
| 53 | + int64_t nLoopLen = 0; | ||
| 54 | + int64_t nLoopNum = 0; | ||
| 55 | + int64_t nLoopTail = 0; | ||
| 56 | + int64_t loopLen = 0; | ||
| 57 | + int64_t lenLoopNum = 0; | ||
| 58 | + int64_t lenLoopTail = 0; | ||
| 59 | + | ||
| 60 | +private: | ||
| 61 | + __aicore__ inline void ProcessInputLoop(int64_t nLoopLen, int64_t baseXOffset, LocalTensor<T1>& scaleLocal); | ||
| 62 | + __aicore__ inline void CopyInParam( | ||
| 63 | + TQue<QuePosition::VECIN, bufferNum>& inQueue, GlobalTensor<T1>& inGm, int64_t paramLen, int64_t paramOffset); | ||
| 64 | + __aicore__ inline void ParseCoreBlocks(const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockS, int64_t& blockLen); | ||
| 65 | + __aicore__ inline void ProcessParamOneLoop(int64_t nLoopLen, int64_t baseSOffset, int64_t baseXOffset); | ||
| 66 | + __aicore__ inline void GetXInCopyParams(const AscendAntiQuantV2TilingData* tilingData, int64_t xN, int64_t xLen, int64_t lastDimLen, | ||
| 67 | + DataCopyExtParams& copyParams); | ||
| 68 | + __aicore__ inline void GetOutCopyParams(const AscendAntiQuantV2TilingData* tilingData, int64_t yN, int64_t yLen, int64_t lastDimLen, | ||
| 69 | + DataCopyExtParams& copyParams); | ||
| 70 | + __aicore__ inline void CopyInX(int64_t xN, int64_t xLen, int64_t xInOffset); | ||
| 71 | + __aicore__ inline void CopyOutY(int64_t yN, int64_t yLen, int64_t yOutOffset); | ||
| 72 | + __aicore__ inline void Compute(int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal); | ||
| 73 | +}; | ||
| 74 | + | ||
| 75 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 76 | +__aicore__ inline void AscendAntiQuantV2PerHeadNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Init( | ||
| 77 | + GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y) | ||
| 78 | +{ | ||
| 79 | + blockIdx_ = GetBlockIdx(); | ||
| 80 | + xGm_.SetGlobalBuffer(reinterpret_cast<__gm__ uint8_t*>(x)); | ||
| 81 | + scaleGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T1*>(scale)); | ||
| 82 | + yGm_.SetGlobalBuffer(reinterpret_cast<__gm__ U*>(y)); | ||
| 83 | + | ||
| 84 | + ParseCoreBlocks(tilingData_, blockIdx_, blockN_, blockS_, blockLen_); | ||
| 85 | + | ||
| 86 | + // calc n size to alloc queue | ||
| 87 | + pipe_.InitBuffer(inQueueX_, bufferNum, tilingData_->baseN * tilingData_->baseLen * sizeof(xCopyDtype)); | ||
| 88 | + pipe_.InitBuffer(inQueueScale_, bufferNum, tilingData_->baseN * sizeof(T1)); | ||
| 89 | + | ||
| 90 | + pipe_.InitBuffer(outQueueY_, bufferNum, tilingData_->baseN * tilingData_->baseLen * sizeof(U)); | ||
| 91 | +} | ||
| 92 | + | ||
| 93 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 94 | +__aicore__ inline void AscendAntiQuantV2PerHeadNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Process() | ||
| 95 | +{ | ||
| 96 | + if (blockIdx_ >= tilingData_->numCore || blockN_ == 0) { | ||
| 97 | + return; | ||
| 98 | + } | ||
| 99 | + if (tilingData_->blockAxis == 0) { | ||
| 100 | + // only split axis 0 | ||
| 101 | + gmXOffset_ = blockIdx_ * tilingData_->blockFactor * tilingData_->dim1 * tilingData_->dim2; | ||
| 102 | + gmSOffset_ = 0; | ||
| 103 | + } else if (tilingData_->blockAxis == 1) { | ||
| 104 | + // only split axis 1, blockUnion means factor per block on split axis | ||
| 105 | + gmXOffset_ = blockIdx_ / tilingData_->blockUnion * tilingData_->dim1 * tilingData_->dim2 + | ||
| 106 | + blockIdx_ % tilingData_->blockUnion * tilingData_->blockFactor * tilingData_->dim2; | ||
| 107 | + gmSOffset_ = blockIdx_ % tilingData_->blockUnion * tilingData_->blockFactor; | ||
| 108 | + } else { | ||
| 109 | + gmXOffset_ = | ||
| 110 | + (blockIdx_ / tilingData_->blockUnion * tilingData_->dim2 + | ||
| 111 | + blockIdx_ % tilingData_->blockUnion * tilingData_->blockFactor); | ||
| 112 | + gmSOffset_ = blockIdx_ / tilingData_->blockUnion; | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + nLoopLen = tilingData_->baseN; | ||
| 116 | + nLoopNum = blockN_ / nLoopLen; | ||
| 117 | + nLoopTail = blockN_ % nLoopLen; | ||
| 118 | + | ||
| 119 | + loopLen = tilingData_->baseLen; | ||
| 120 | + lenLoopNum = blockLen_ / loopLen; | ||
| 121 | + lenLoopTail = blockLen_ % loopLen; | ||
| 122 | + | ||
| 123 | + for (int64_t i = 0; i < blockS_; ++i) { | ||
| 124 | + // scale allows start from begin on each core | ||
| 125 | + int64_t baseSOffset = gmSOffset_; | ||
| 126 | + int64_t baseXOffset = gmXOffset_; | ||
| 127 | + | ||
| 128 | + for (int64_t i = 0; i < nLoopNum; ++i) { | ||
| 129 | + ProcessParamOneLoop(nLoopLen, baseSOffset, baseXOffset); | ||
| 130 | + baseXOffset += nLoopLen * tilingData_->dim2; | ||
| 131 | + baseSOffset += tilingData_->baseN; | ||
| 132 | + } | ||
| 133 | + if (nLoopTail != 0) { | ||
| 134 | + ProcessParamOneLoop(nLoopTail, baseSOffset, baseXOffset); | ||
| 135 | + } | ||
| 136 | + gmXOffset_ += tilingData_->dim1 * tilingData_->dim2; | ||
| 137 | + } | ||
| 138 | +} | ||
| 139 | + | ||
| 140 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 141 | +__aicore__ inline void AscendAntiQuantV2PerHeadNoOffsetRegbase<T, T1, T2, U, SqrtMode>::ProcessParamOneLoop( | ||
| 142 | + int64_t nLoopLen, int64_t baseSOffset, int64_t baseXOffset) | ||
| 143 | +{ | ||
| 144 | + // copy in scale | ||
| 145 | + CopyInParam(inQueueScale_, scaleGm_, nLoopLen, baseSOffset % tilingData_->dim1); | ||
| 146 | + auto scaleLocal = inQueueScale_.DeQue<T1>(); | ||
| 147 | + ProcessInputLoop(nLoopLen, baseXOffset, scaleLocal); | ||
| 148 | + | ||
| 149 | + inQueueScale_.FreeTensor(scaleLocal); | ||
| 150 | +} | ||
| 151 | + | ||
| 152 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 153 | +__aicore__ inline void AscendAntiQuantV2PerHeadNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyInParam( | ||
| 154 | + TQue<QuePosition::VECIN, bufferNum>& inQueue, GlobalTensor<T1>& inGm, int64_t paramLen, int64_t paramOffset) | ||
| 155 | +{ | ||
| 156 | + auto paramLocal = inQueue.AllocTensor<T1>(); | ||
| 157 | + DataCopyExtParams copyParams; | ||
| 158 | + copyParams.blockCount = 1; | ||
| 159 | + copyParams.blockLen = paramLen * sizeof(T1); | ||
| 160 | + copyParams.dstStride = 0; | ||
| 161 | + copyParams.srcStride = 0; | ||
| 162 | + copyParams.rsv = 0; | ||
| 163 | + DataCopyPad(paramLocal, inGm[paramOffset], copyParams, {false, 0, 0, 0}); | ||
| 164 | + inQueue.EnQue(paramLocal); | ||
| 165 | +} | ||
| 166 | + | ||
| 167 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 168 | +__aicore__ inline void AscendAntiQuantV2PerHeadNoOffsetRegbase<T, T1, T2, U, SqrtMode>::ParseCoreBlocks( | ||
| 169 | + const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockS, int64_t& blockLen) | ||
| 170 | +{ | ||
| 171 | + if (tilingData->blockAxis == 0) { | ||
| 172 | + // blockFactor is in [1, S] | ||
| 173 | + if (blockIdx == tilingData->numCore - 1) { | ||
| 174 | + blockS = tilingData->blockTailFactor; | ||
| 175 | + } else { | ||
| 176 | + blockS = tilingData->blockFactor; | ||
| 177 | + } | ||
| 178 | + blockN = tilingData->dim1; | ||
| 179 | + blockLen = tilingData->dim2; | ||
| 180 | + } else if (tilingData->blockAxis == 1) { | ||
| 181 | + // blockFactor is in [1, N], blockUnion is in [1, N/blockFactor] | ||
| 182 | + if (blockIdx % tilingData->blockUnion == tilingData->blockUnion - 1) { | ||
| 183 | + blockN = tilingData->blockTailFactor; | ||
| 184 | + } else { | ||
| 185 | + blockN = tilingData->blockFactor; | ||
| 186 | + } | ||
| 187 | + blockLen = tilingData->dim2; | ||
| 188 | + } else { | ||
| 189 | + // blockFactor is in [1, D] | ||
| 190 | + blockN = 1; | ||
| 191 | + if (blockIdx % tilingData->blockUnion == tilingData->blockUnion - 1) { | ||
| 192 | + blockLen = tilingData->blockTailFactor; | ||
| 193 | + } else { | ||
| 194 | + blockLen = tilingData->blockFactor; | ||
| 195 | + } | ||
| 196 | + } | ||
| 197 | +} | ||
| 198 | + | ||
| 199 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 200 | +__aicore__ inline void AscendAntiQuantV2PerHeadNoOffsetRegbase<T, T1, T2, U, SqrtMode>::ProcessInputLoop( | ||
| 201 | + int64_t nLoopLen, int64_t baseXOffset, LocalTensor<T1>& scaleLocal) | ||
| 202 | +{ | ||
| 203 | + for (auto i = 0; i < lenLoopNum; ++i) { | ||
| 204 | + CopyInX(nLoopLen, loopLen, baseXOffset); | ||
| 205 | + Compute(nLoopLen, loopLen, scaleLocal); | ||
| 206 | + CopyOutY(nLoopLen, loopLen, baseXOffset); | ||
| 207 | + baseXOffset += tilingData_->baseLen; | ||
| 208 | + } | ||
| 209 | + if (lenLoopTail != 0) { | ||
| 210 | + CopyInX(nLoopLen, lenLoopTail, baseXOffset); | ||
| 211 | + Compute(nLoopLen, lenLoopTail, scaleLocal); | ||
| 212 | + CopyOutY(nLoopLen, lenLoopTail, baseXOffset); | ||
| 213 | + } | ||
| 214 | +} | ||
| 215 | + | ||
| 216 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 217 | +__aicore__ inline void AscendAntiQuantV2PerHeadNoOffsetRegbase<T, T1, T2, U, SqrtMode>::GetXInCopyParams( | ||
| 218 | + const AscendAntiQuantV2TilingData* tilingData, int64_t xN, int64_t xLen, int64_t lastDimLen, | ||
| 219 | + DataCopyExtParams& copyParams) | ||
| 220 | +{ | ||
| 221 | + int64_t xLenReal = xLen; | ||
| 222 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 223 | + xLenReal = xLenReal / this->INT4_NUMS_IN_INT8_SPACE; | ||
| 224 | + } | ||
| 225 | + | ||
| 226 | + copyParams.blockCount = xN; | ||
| 227 | + copyParams.blockLen = xLenReal * sizeof(xCopyDtype); | ||
| 228 | + if (lastDimLen > xLen) { | ||
| 229 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 230 | + copyParams.srcStride = (lastDimLen - xLen) * sizeof(xCopyDtype) / this->INT4_NUMS_IN_INT8_SPACE; | ||
| 231 | + } else { | ||
| 232 | + copyParams.srcStride = (lastDimLen - xLen) * sizeof(xCopyDtype); | ||
| 233 | + } | ||
| 234 | + } else { | ||
| 235 | + copyParams.srcStride = 0; | ||
| 236 | + } | ||
| 237 | + if (tilingData->baseLen > xLenReal) { | ||
| 238 | + copyParams.dstStride = (tilingData->baseLen - xLenReal) * sizeof(xCopyDtype) / this->BLOCK_SIZE; | ||
| 239 | + } else { | ||
| 240 | + copyParams.dstStride = 0; | ||
| 241 | + } | ||
| 242 | +} | ||
| 243 | + | ||
| 244 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 245 | +__aicore__ inline void AscendAntiQuantV2PerHeadNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyInX( | ||
| 246 | + int64_t xN, int64_t xLen, int64_t xInOffset) | ||
| 247 | +{ | ||
| 248 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 249 | + xInOffset = xInOffset >> 1; | ||
| 250 | + } | ||
| 251 | + | ||
| 252 | + LocalTensor<uint8_t> xLocal = inQueueX_.AllocTensor<uint8_t>(); | ||
| 253 | + DataCopyExtParams copyParams; | ||
| 254 | + DataCopyPadExtParams<uint8_t> padParams = {false, 0, 0, 0}; | ||
| 255 | + GetXInCopyParams(tilingData_, xN, xLen, tilingData_->dim2, copyParams); | ||
| 256 | + DataCopyPad<uint8_t>(xLocal, xGm_[xInOffset], copyParams, padParams); | ||
| 257 | + inQueueX_.EnQue(xLocal); | ||
| 258 | +} | ||
| 259 | + | ||
| 260 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 261 | +__aicore__ inline void AscendAntiQuantV2PerHeadNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Compute( | ||
| 262 | + int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal) | ||
| 263 | +{ | ||
| 264 | + LocalTensor<xCopyDtype> xLocal = inQueueX_.DeQue<xCopyDtype>(); | ||
| 265 | + LocalTensor<U> outLocal = outQueueY_.AllocTensor<U>(); | ||
| 266 | + | ||
| 267 | + __local_mem__ xCopyDtype* xLocalAddr = (__local_mem__ xCopyDtype*)xLocal.GetPhyAddr(); | ||
| 268 | + __local_mem__ T1* scaleLocalAddr = (__local_mem__ T1*)sLocal.GetPhyAddr(); | ||
| 269 | + __local_mem__ U* outLocalAddr = (__local_mem__ U*)outLocal.GetPhyAddr(); | ||
| 270 | + | ||
| 271 | + uint16_t VL = AscendC::VECTOR_REG_WIDTH / sizeof(float); | ||
| 272 | + uint16_t HalfVL = VL / 2; | ||
| 273 | + uint16_t vfLoopNum = (dataCount + VL - 1) / VL; | ||
| 274 | + | ||
| 275 | + uint32_t xLocalOffset = static_cast<uint32_t>(tilingData_->baseLen); | ||
| 276 | + | ||
| 277 | + // has offset | ||
| 278 | + __VEC_SCOPE__ | ||
| 279 | + { | ||
| 280 | + // x: int4, int8, hifp8, fp8_e5m2, fp8_e4m3 | ||
| 281 | + AscendC::Reg::RegTensor<xCopyDtype> vregX; | ||
| 282 | + AscendC::Reg::RegTensor<half> vregHalfX; | ||
| 283 | + AscendC::Reg::RegTensor<float> vregFloatX; | ||
| 284 | + // scales: fp32, bf16 | ||
| 285 | + AscendC::Reg::RegTensor<T1> vregS; | ||
| 286 | + AscendC::Reg::RegTensor<float> vregFloatS; | ||
| 287 | + // y: fp16, bf16 | ||
| 288 | + AscendC::Reg::RegTensor<float> vregFloatY; | ||
| 289 | + AscendC::Reg::RegTensor<U> vregY; | ||
| 290 | + | ||
| 291 | + AscendC::Reg::MaskReg mask; | ||
| 292 | + | ||
| 293 | + mask = AscendC::Reg::CreateMask<float>(); | ||
| 294 | + for (uint16_t j = 0; j < static_cast<uint16_t>(nRow); ++j) { | ||
| 295 | + uint32_t count = dataCount; | ||
| 296 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 297 | + mask = AscendC::Reg::UpdateMask<float>(count); | ||
| 298 | + // ld and cast for x | ||
| 299 | + if constexpr (IsSameType<T, hifloat8_t>::value) { | ||
| 300 | + // hifp8 | ||
| 301 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 302 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 303 | + AscendC::Reg::Cast< | ||
| 304 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HIFP8_TO_FP32>( | ||
| 305 | + vregFloatX, vregX, mask); | ||
| 306 | + } else if constexpr (IsSameType<T, fp8_e5m2_t>::value) { | ||
| 307 | + // fp8_e5m2 | ||
| 308 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 309 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 310 | + AscendC::Reg::Cast< | ||
| 311 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E5M2_TO_FP32>( | ||
| 312 | + vregFloatX, vregX, mask); | ||
| 313 | + } else if constexpr (IsSameType<T, fp8_e4m3fn_t>::value) { | ||
| 314 | + // fp8_e4m3 | ||
| 315 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 316 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 317 | + AscendC::Reg::Cast< | ||
| 318 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E4M3_TO_FP32>( | ||
| 319 | + vregFloatX, vregX, mask); | ||
| 320 | + } else if constexpr (IsSameType<T, int8_t>::value) { | ||
| 321 | + // int8 | ||
| 322 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 323 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 324 | + AscendC::Reg::Cast< | ||
| 325 | + half, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 326 | + vregHalfX, vregX, mask); | ||
| 327 | + AscendC::Reg::Cast< | ||
| 328 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 329 | + vregFloatX, vregHalfX, mask); | ||
| 330 | + } else if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 331 | + // int4 | ||
| 332 | + AscendC::Reg::RegTensor<half> vregTmpX; | ||
| 333 | + AscendC::Reg::RegTensor<uint16_t> vregTmpU16X; | ||
| 334 | + AscendC::Reg::DataCopy<xCopyDtype, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 335 | + vregX, xLocalAddr + i * HalfVL + j * xLocalOffset); | ||
| 336 | + AscendC::Reg::Cast< | ||
| 337 | + half, int4x2_t, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 338 | + (AscendC::Reg::RegTensor<half>&)vregTmpU16X, | ||
| 339 | + (AscendC::Reg::RegTensor<int4x2_t>&)vregX, mask); | ||
| 340 | + AscendC::Reg::UnPack((AscendC::Reg::RegTensor<uint32_t>&)vregTmpX, vregTmpU16X); | ||
| 341 | + AscendC::Reg::Cast< | ||
| 342 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 343 | + vregFloatX, vregTmpX, mask); | ||
| 344 | + } | ||
| 345 | + | ||
| 346 | + // ld and cast for scale | ||
| 347 | + if constexpr (IsSameType<T1, float>::value) { | ||
| 348 | + // fp32 | ||
| 349 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_BRC_B32>( | ||
| 350 | + vregFloatS, scaleLocalAddr + j); | ||
| 351 | + } else if constexpr (IsSameType<T1, bfloat16_t>::value) { | ||
| 352 | + // bf16 | ||
| 353 | + AscendC::Reg::DataCopy<T1, AscendC::Reg::LoadDist::DIST_BRC_B16>(vregS, scaleLocalAddr + j); | ||
| 354 | + AscendC::Reg::Cast< | ||
| 355 | + float, T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 356 | + vregFloatS, vregS, mask); | ||
| 357 | + } | ||
| 358 | + | ||
| 359 | + // compute | ||
| 360 | + if constexpr (SqrtMode == TPL_SQRT_MODE) { | ||
| 361 | + AscendC::Reg::Mul(vregFloatS, vregFloatS, vregFloatS, mask); | ||
| 362 | + } | ||
| 363 | + AscendC::Reg::Mul(vregFloatY, vregFloatX, vregFloatS, mask); | ||
| 364 | + | ||
| 365 | + // cast and sd for y | ||
| 366 | + if constexpr (IsSameType<U, half>::value) { | ||
| 367 | + // fp16 | ||
| 368 | + AscendC::Reg::Cast< | ||
| 369 | + half, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_HALF>( | ||
| 370 | + vregY, vregFloatY, mask); | ||
| 371 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 372 | + outLocalAddr + i * VL + j * xLocalOffset, vregY, mask); | ||
| 373 | + } else if constexpr (IsSameType<U, bfloat16_t>::value) { | ||
| 374 | + // bf16 | ||
| 375 | + AscendC::Reg::Cast< | ||
| 376 | + U, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_BF16>( | ||
| 377 | + vregY, vregFloatY, mask); | ||
| 378 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 379 | + outLocalAddr + i * VL + j * xLocalOffset, vregY, mask); | ||
| 380 | + } | ||
| 381 | + } | ||
| 382 | + } | ||
| 383 | + } | ||
| 384 | + inQueueX_.FreeTensor(xLocal); | ||
| 385 | + outQueueY_.EnQue(outLocal); | ||
| 386 | +} | ||
| 387 | + | ||
| 388 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 389 | +__aicore__ inline void AscendAntiQuantV2PerHeadNoOffsetRegbase<T, T1, T2, U, SqrtMode>::GetOutCopyParams( | ||
| 390 | + const AscendAntiQuantV2TilingData* tilingData, int64_t yN, int64_t yLen, int64_t lastDimLen, | ||
| 391 | + DataCopyExtParams& copyParams) | ||
| 392 | +{ | ||
| 393 | + copyParams.blockCount = yN; | ||
| 394 | + copyParams.blockLen = yLen * sizeof(U); | ||
| 395 | + if (tilingData->baseLen > yLen) { | ||
| 396 | + copyParams.srcStride = (tilingData->baseLen - yLen) * sizeof(U) / this->BLOCK_SIZE; | ||
| 397 | + } else { | ||
| 398 | + copyParams.srcStride = 0; | ||
| 399 | + } | ||
| 400 | + if (lastDimLen > yLen) { | ||
| 401 | + copyParams.dstStride = (lastDimLen - yLen) * sizeof(U); | ||
| 402 | + } else { | ||
| 403 | + copyParams.dstStride = 0; | ||
| 404 | + } | ||
| 405 | +} | ||
| 406 | + | ||
| 407 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 408 | +__aicore__ inline void AscendAntiQuantV2PerHeadNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyOutY( | ||
| 409 | + int64_t yN, int64_t yLen, int64_t yOutOffset) | ||
| 410 | +{ | ||
| 411 | + LocalTensor<U> outLocal = outQueueY_.DeQue<U>(); | ||
| 412 | + DataCopyExtParams copyParams; | ||
| 413 | + GetOutCopyParams(tilingData_, yN, yLen, tilingData_->dim2, copyParams); | ||
| 414 | + DataCopyPad<U>(yGm_[yOutOffset], outLocal, copyParams); | ||
| 415 | + outQueueY_.FreeTensor(outLocal); | ||
| 416 | +} | ||
| 417 | +} // namespace AscendAntiQuantV2 | ||
| 418 | + | ||
| @@ -0,0 +1,447 @@ | |||
| 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 ascend_anti_quant_v2_per_head_regbase.h | ||
| 13 | + * \brief ascendantiquantv2 kernel | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +namespace AscendAntiQuantV2 { | ||
| 26 | +using namespace AscendC; | ||
| 27 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 28 | +class AscendAntiQuantV2PerHeadRegbase : public AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode> { | ||
| 29 | +public: | ||
| 30 | + __aicore__ inline AscendAntiQuantV2PerHeadRegbase(const AscendAntiQuantV2TilingData* tilingData) | ||
| 31 | + : tilingData_(tilingData){}; | ||
| 32 | + __aicore__ inline void Init(GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y); | ||
| 33 | + __aicore__ inline void Process(); | ||
| 34 | + | ||
| 35 | +private: | ||
| 36 | + using xCopyDtype = std::conditional_t<IsSameType<T, int4b_t>::value, uint8_t, T>; | ||
| 37 | + TPipe pipe_; | ||
| 38 | + constexpr static int32_t bufferNum = 2; | ||
| 39 | + TQue<QuePosition::VECIN, bufferNum> inQueueX_; | ||
| 40 | + TQue<QuePosition::VECIN, bufferNum> inQueueScale_; | ||
| 41 | + TQue<QuePosition::VECIN, bufferNum> inQueueOffset_; | ||
| 42 | + TQue<QuePosition::VECOUT, bufferNum> outQueueY_; | ||
| 43 | + GlobalTensor<uint8_t> xGm_; | ||
| 44 | + GlobalTensor<T1> scaleGm_; | ||
| 45 | + GlobalTensor<T2> offsetGm_; | ||
| 46 | + GlobalTensor<U> yGm_; | ||
| 47 | + | ||
| 48 | + const AscendAntiQuantV2TilingData* tilingData_; | ||
| 49 | + int32_t blockIdx_ = 0; | ||
| 50 | + int64_t gmXOffset_ = 0; | ||
| 51 | + int64_t gmSOffset_ = 0; | ||
| 52 | + int64_t blockN_ = 1; | ||
| 53 | + int64_t blockLen_ = 1; | ||
| 54 | + int64_t blockS_ = 1; | ||
| 55 | + int64_t nLoopLen = 0; | ||
| 56 | + int64_t nLoopNum = 0; | ||
| 57 | + int64_t nLoopTail = 0; | ||
| 58 | + int64_t loopLen = 0; | ||
| 59 | + int64_t lenLoopNum = 0; | ||
| 60 | + int64_t lenLoopTail = 0; | ||
| 61 | + | ||
| 62 | +private: | ||
| 63 | + __aicore__ inline void ProcessInputLoop( | ||
| 64 | + int64_t nLoopLen, int64_t baseXOffset, LocalTensor<T1>& scaleLocal, LocalTensor<T2>& offsetLocal); | ||
| 65 | + template <typename dtypeCopyIn> | ||
| 66 | + __aicore__ inline void CopyInParam( | ||
| 67 | + TQue<QuePosition::VECIN, bufferNum>& inQueue, GlobalTensor<dtypeCopyIn>& inGm, int64_t paramLen, int64_t paramOffset); | ||
| 68 | + __aicore__ inline void ParseCoreBlocks(const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockS, int64_t& blockLen); | ||
| 69 | + __aicore__ inline void ProcessParamOneLoop(int64_t nLoopLen, int64_t baseSOffset, int64_t baseXOffset); | ||
| 70 | + __aicore__ inline void GetXInCopyParams(const AscendAntiQuantV2TilingData* tilingData, int64_t xN, int64_t xLen, int64_t lastDimLen, | ||
| 71 | + DataCopyExtParams& copyParams); | ||
| 72 | + __aicore__ inline void GetOutCopyParams(const AscendAntiQuantV2TilingData* tilingData, int64_t yN, int64_t yLen, int64_t lastDimLen, | ||
| 73 | + DataCopyExtParams& copyParams); | ||
| 74 | + __aicore__ inline void CopyInX(int64_t xN, int64_t xLen, int64_t xInOffset); | ||
| 75 | + __aicore__ inline void CopyOutY(int64_t yN, int64_t yLen, int64_t yOutOffset); | ||
| 76 | + __aicore__ inline void Compute(int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal); | ||
| 77 | +}; | ||
| 78 | + | ||
| 79 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 80 | +__aicore__ inline void AscendAntiQuantV2PerHeadRegbase<T, T1, T2, U, SqrtMode>::Init( | ||
| 81 | + GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y) | ||
| 82 | +{ | ||
| 83 | + blockIdx_ = GetBlockIdx(); | ||
| 84 | + xGm_.SetGlobalBuffer(reinterpret_cast<__gm__ uint8_t*>(x)); | ||
| 85 | + scaleGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T1*>(scale)); | ||
| 86 | + offsetGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T2*>(offset)); | ||
| 87 | + yGm_.SetGlobalBuffer(reinterpret_cast<__gm__ U*>(y)); | ||
| 88 | + | ||
| 89 | + ParseCoreBlocks(tilingData_, blockIdx_, blockN_, blockS_, blockLen_); | ||
| 90 | + | ||
| 91 | + // calc n size to alloc queue | ||
| 92 | + pipe_.InitBuffer(inQueueX_, bufferNum, tilingData_->baseN * tilingData_->baseLen * sizeof(xCopyDtype)); | ||
| 93 | + pipe_.InitBuffer(inQueueScale_, bufferNum, tilingData_->baseN * sizeof(T1)); | ||
| 94 | + pipe_.InitBuffer(inQueueOffset_, bufferNum, tilingData_->baseN * sizeof(T2)); | ||
| 95 | + | ||
| 96 | + pipe_.InitBuffer(outQueueY_, bufferNum, tilingData_->baseN * tilingData_->baseLen * sizeof(U)); | ||
| 97 | +} | ||
| 98 | + | ||
| 99 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 100 | +__aicore__ inline void AscendAntiQuantV2PerHeadRegbase<T, T1, T2, U, SqrtMode>::Process() | ||
| 101 | +{ | ||
| 102 | + if (blockIdx_ >= tilingData_->numCore || blockN_ == 0) { | ||
| 103 | + return; | ||
| 104 | + } | ||
| 105 | + if (tilingData_->blockAxis == 0) { | ||
| 106 | + // only split axis 0 | ||
| 107 | + gmXOffset_ = blockIdx_ * tilingData_->blockFactor * tilingData_->dim1 * tilingData_->dim2; | ||
| 108 | + gmSOffset_ = 0; | ||
| 109 | + } else if (tilingData_->blockAxis == 1) { | ||
| 110 | + // only split axis 1, blockUnion means factor per block on split axis | ||
| 111 | + gmXOffset_ = blockIdx_ / tilingData_->blockUnion * tilingData_->dim1 * tilingData_->dim2 + | ||
| 112 | + blockIdx_ % tilingData_->blockUnion * tilingData_->blockFactor * tilingData_->dim2; | ||
| 113 | + gmSOffset_ = blockIdx_ % tilingData_->blockUnion * tilingData_->blockFactor; | ||
| 114 | + } else { | ||
| 115 | + gmXOffset_ = | ||
| 116 | + (blockIdx_ / tilingData_->blockUnion * tilingData_->dim2 + | ||
| 117 | + blockIdx_ % tilingData_->blockUnion * tilingData_->blockFactor); | ||
| 118 | + gmSOffset_ = blockIdx_ / tilingData_->blockUnion; | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + nLoopLen = tilingData_->baseN; | ||
| 122 | + nLoopNum = blockN_ / nLoopLen; | ||
| 123 | + nLoopTail = blockN_ % nLoopLen; | ||
| 124 | + | ||
| 125 | + loopLen = tilingData_->baseLen; | ||
| 126 | + lenLoopNum = blockLen_ / loopLen; | ||
| 127 | + lenLoopTail = blockLen_ % loopLen; | ||
| 128 | + | ||
| 129 | + for (int64_t i = 0; i < blockS_; ++i) { | ||
| 130 | + // scale allows start from begin on each core | ||
| 131 | + int64_t baseSOffset = gmSOffset_; | ||
| 132 | + int64_t baseXOffset = gmXOffset_; | ||
| 133 | + | ||
| 134 | + for (int64_t i = 0; i < nLoopNum; ++i) { | ||
| 135 | + ProcessParamOneLoop(nLoopLen, baseSOffset, baseXOffset); | ||
| 136 | + baseXOffset += nLoopLen * tilingData_->dim2; | ||
| 137 | + baseSOffset += tilingData_->baseN; | ||
| 138 | + } | ||
| 139 | + if (nLoopTail != 0) { | ||
| 140 | + ProcessParamOneLoop(nLoopTail, baseSOffset, baseXOffset); | ||
| 141 | + } | ||
| 142 | + gmXOffset_ += tilingData_->dim1 * tilingData_->dim2; | ||
| 143 | + } | ||
| 144 | +} | ||
| 145 | + | ||
| 146 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 147 | +__aicore__ inline void AscendAntiQuantV2PerHeadRegbase<T, T1, T2, U, SqrtMode>::ProcessParamOneLoop(int64_t nLoopLen, int64_t baseSOffset, int64_t baseXOffset) | ||
| 148 | +{ | ||
| 149 | + // copy in scale and offset | ||
| 150 | + CopyInParam<T1>(inQueueScale_, scaleGm_, nLoopLen, baseSOffset % tilingData_->dim1); | ||
| 151 | + auto scaleLocal = inQueueScale_.DeQue<T1>(); | ||
| 152 | + CopyInParam<T2>(inQueueOffset_, offsetGm_, nLoopLen, baseSOffset % tilingData_->dim1); | ||
| 153 | + auto offsetLocal = inQueueOffset_.DeQue<T2>(); | ||
| 154 | + ProcessInputLoop(nLoopLen, baseXOffset, scaleLocal, offsetLocal); | ||
| 155 | + inQueueOffset_.FreeTensor(offsetLocal); | ||
| 156 | + | ||
| 157 | + inQueueScale_.FreeTensor(scaleLocal); | ||
| 158 | +} | ||
| 159 | + | ||
| 160 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 161 | +template <typename dtypeCopyIn> | ||
| 162 | +__aicore__ inline void AscendAntiQuantV2PerHeadRegbase<T, T1, T2, U, SqrtMode>::CopyInParam( | ||
| 163 | + TQue<QuePosition::VECIN, bufferNum>& inQueue, GlobalTensor<dtypeCopyIn>& inGm, int64_t paramLen, | ||
| 164 | + int64_t paramOffset) | ||
| 165 | +{ | ||
| 166 | + auto paramLocal = inQueue.AllocTensor<dtypeCopyIn>(); | ||
| 167 | + DataCopyExtParams copyParams; | ||
| 168 | + copyParams.blockCount = 1; | ||
| 169 | + copyParams.blockLen = paramLen * sizeof(dtypeCopyIn); | ||
| 170 | + copyParams.dstStride = 0; | ||
| 171 | + copyParams.srcStride = 0; | ||
| 172 | + copyParams.rsv = 0; | ||
| 173 | + DataCopyPad(paramLocal, inGm[paramOffset], copyParams, {false, 0, 0, 0}); | ||
| 174 | + inQueue.EnQue(paramLocal); | ||
| 175 | +} | ||
| 176 | + | ||
| 177 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 178 | +__aicore__ inline void AscendAntiQuantV2PerHeadRegbase<T, T1, T2, U, SqrtMode>::ParseCoreBlocks( | ||
| 179 | + const AscendAntiQuantV2TilingData* tilingData, int32_t blockIdx, int64_t& blockN, int64_t& blockS, int64_t& blockLen) | ||
| 180 | +{ | ||
| 181 | + if (tilingData->blockAxis == 0) { | ||
| 182 | + // blockFactor is in [1, S] | ||
| 183 | + if (blockIdx == tilingData->numCore - 1) { | ||
| 184 | + blockS = tilingData->blockTailFactor; | ||
| 185 | + } else { | ||
| 186 | + blockS = tilingData->blockFactor; | ||
| 187 | + } | ||
| 188 | + blockN = tilingData->dim1; | ||
| 189 | + blockLen = tilingData->dim2; | ||
| 190 | + } else if (tilingData->blockAxis == 1) { | ||
| 191 | + // blockFactor is in [1, N], blockUnion is in [1, N/blockFactor] | ||
| 192 | + if (blockIdx % tilingData->blockUnion == tilingData->blockUnion - 1) { | ||
| 193 | + blockN = tilingData->blockTailFactor; | ||
| 194 | + } else { | ||
| 195 | + blockN = tilingData->blockFactor; | ||
| 196 | + } | ||
| 197 | + blockLen = tilingData->dim2; | ||
| 198 | + } else { | ||
| 199 | + // blockFactor is in [1, D] | ||
| 200 | + blockN = 1; | ||
| 201 | + if (blockIdx % tilingData->blockUnion == tilingData->blockUnion - 1) { | ||
| 202 | + blockLen = tilingData->blockTailFactor; | ||
| 203 | + } else { | ||
| 204 | + blockLen = tilingData->blockFactor; | ||
| 205 | + } | ||
| 206 | + } | ||
| 207 | +} | ||
| 208 | + | ||
| 209 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 210 | +__aicore__ inline void AscendAntiQuantV2PerHeadRegbase<T, T1, T2, U, SqrtMode>::ProcessInputLoop( | ||
| 211 | + int64_t nLoopLen, int64_t baseXOffset, LocalTensor<T1>& scaleLocal, LocalTensor<T2>& offsetLocal) | ||
| 212 | +{ | ||
| 213 | + for (auto i = 0; i < lenLoopNum; ++i) { | ||
| 214 | + CopyInX(nLoopLen, loopLen, baseXOffset); | ||
| 215 | + Compute(nLoopLen, loopLen, scaleLocal, offsetLocal); | ||
| 216 | + CopyOutY(nLoopLen, loopLen, baseXOffset); | ||
| 217 | + baseXOffset += tilingData_->baseLen; | ||
| 218 | + } | ||
| 219 | + if (lenLoopTail != 0) { | ||
| 220 | + CopyInX(nLoopLen, lenLoopTail, baseXOffset); | ||
| 221 | + Compute(nLoopLen, lenLoopTail, scaleLocal, offsetLocal); | ||
| 222 | + CopyOutY(nLoopLen, lenLoopTail, baseXOffset); | ||
| 223 | + } | ||
| 224 | +} | ||
| 225 | + | ||
| 226 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 227 | +__aicore__ inline void AscendAntiQuantV2PerHeadRegbase<T, T1, T2, U, SqrtMode>::GetXInCopyParams( | ||
| 228 | + const AscendAntiQuantV2TilingData* tilingData, int64_t xN, int64_t xLen, int64_t lastDimLen, | ||
| 229 | + DataCopyExtParams& copyParams) | ||
| 230 | +{ | ||
| 231 | + int64_t xLenReal = xLen; | ||
| 232 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 233 | + xLenReal = xLenReal / this->INT4_NUMS_IN_INT8_SPACE; | ||
| 234 | + } | ||
| 235 | + | ||
| 236 | + copyParams.blockCount = xN; | ||
| 237 | + copyParams.blockLen = xLenReal * sizeof(xCopyDtype); | ||
| 238 | + if (lastDimLen > xLen) { | ||
| 239 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 240 | + copyParams.srcStride = (lastDimLen - xLen) * sizeof(xCopyDtype) / this->INT4_NUMS_IN_INT8_SPACE; | ||
| 241 | + } else { | ||
| 242 | + copyParams.srcStride = (lastDimLen - xLen) * sizeof(xCopyDtype); | ||
| 243 | + } | ||
| 244 | + } else { | ||
| 245 | + copyParams.srcStride = 0; | ||
| 246 | + } | ||
| 247 | + if (tilingData->baseLen > xLenReal) { | ||
| 248 | + copyParams.dstStride = (tilingData->baseLen - xLenReal) * sizeof(xCopyDtype) / this->BLOCK_SIZE; | ||
| 249 | + } else { | ||
| 250 | + copyParams.dstStride = 0; | ||
| 251 | + } | ||
| 252 | +} | ||
| 253 | + | ||
| 254 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 255 | +__aicore__ inline void AscendAntiQuantV2PerHeadRegbase<T, T1, T2, U, SqrtMode>::CopyInX( | ||
| 256 | + int64_t xN, int64_t xLen, int64_t xInOffset) | ||
| 257 | +{ | ||
| 258 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 259 | + xInOffset = xInOffset >> 1; | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + LocalTensor<uint8_t> xLocal = inQueueX_.AllocTensor<uint8_t>(); | ||
| 263 | + DataCopyExtParams copyParams; | ||
| 264 | + DataCopyPadExtParams<uint8_t> padParams = {false, 0, 0, 0}; | ||
| 265 | + GetXInCopyParams(tilingData_, xN, xLen, tilingData_->dim2, copyParams); | ||
| 266 | + DataCopyPad<uint8_t>(xLocal, xGm_[xInOffset], copyParams, padParams); | ||
| 267 | + inQueueX_.EnQue(xLocal); | ||
| 268 | +} | ||
| 269 | + | ||
| 270 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 271 | +__aicore__ inline void AscendAntiQuantV2PerHeadRegbase<T, T1, T2, U, SqrtMode>::Compute( | ||
| 272 | + int64_t nRow, int64_t dataCount, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal) | ||
| 273 | +{ | ||
| 274 | + LocalTensor<xCopyDtype> xLocal = inQueueX_.DeQue<xCopyDtype>(); | ||
| 275 | + LocalTensor<U> outLocal = outQueueY_.AllocTensor<U>(); | ||
| 276 | + | ||
| 277 | + __local_mem__ xCopyDtype* xLocalAddr = (__local_mem__ xCopyDtype*)xLocal.GetPhyAddr(); | ||
| 278 | + __local_mem__ T1* scaleLocalAddr = (__local_mem__ T1*)sLocal.GetPhyAddr(); | ||
| 279 | + __local_mem__ T2* offsetLocalAddr = (__local_mem__ T2*)oLocal.GetPhyAddr(); | ||
| 280 | + __local_mem__ U* outLocalAddr = (__local_mem__ U*)outLocal.GetPhyAddr(); | ||
| 281 | + | ||
| 282 | + uint16_t VL = AscendC::VECTOR_REG_WIDTH / sizeof(float); | ||
| 283 | + uint16_t HalfVL = VL / 2; | ||
| 284 | + uint16_t vfLoopNum = (dataCount + VL - 1) / VL; | ||
| 285 | + | ||
| 286 | + uint32_t xLocalOffset = static_cast<uint32_t>(tilingData_->baseLen); | ||
| 287 | + | ||
| 288 | + // has offset | ||
| 289 | + __VEC_SCOPE__ | ||
| 290 | + { | ||
| 291 | + // x: int4, int8, hifp8, fp8_e5m2, fp8_e4m3 | ||
| 292 | + AscendC::Reg::RegTensor<xCopyDtype> vregX; | ||
| 293 | + AscendC::Reg::RegTensor<half> vregHalfX; | ||
| 294 | + AscendC::Reg::RegTensor<float> vregFloatX; | ||
| 295 | + // scales: fp32, bf16 | ||
| 296 | + AscendC::Reg::RegTensor<T1> vregS; | ||
| 297 | + AscendC::Reg::RegTensor<float> vregFloatS; | ||
| 298 | + // offset: fp32, bf16 | ||
| 299 | + AscendC::Reg::RegTensor<T2> vregO; | ||
| 300 | + AscendC::Reg::RegTensor<float> vregFloatO; | ||
| 301 | + // y: fp16, bf16 | ||
| 302 | + AscendC::Reg::RegTensor<float> vregFloatY; | ||
| 303 | + AscendC::Reg::RegTensor<U> vregY; | ||
| 304 | + | ||
| 305 | + AscendC::Reg::RegTensor<float> vregTmp1; | ||
| 306 | + AscendC::Reg::MaskReg mask; | ||
| 307 | + | ||
| 308 | + mask = AscendC::Reg::CreateMask<float>(); | ||
| 309 | + for (uint16_t j = 0; j < static_cast<uint16_t>(nRow); ++j) { | ||
| 310 | + uint32_t count = dataCount; | ||
| 311 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 312 | + mask = AscendC::Reg::UpdateMask<float>(count); | ||
| 313 | + // ld and cast for x | ||
| 314 | + if constexpr (IsSameType<T, hifloat8_t>::value) { | ||
| 315 | + // hifp8 | ||
| 316 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 317 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 318 | + AscendC::Reg::Cast< | ||
| 319 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HIFP8_TO_FP32>( | ||
| 320 | + vregFloatX, vregX, mask); | ||
| 321 | + } else if constexpr (IsSameType<T, fp8_e5m2_t>::value) { | ||
| 322 | + // fp8_e5m2 | ||
| 323 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 324 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 325 | + AscendC::Reg::Cast< | ||
| 326 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E5M2_TO_FP32>( | ||
| 327 | + vregFloatX, vregX, mask); | ||
| 328 | + } else if constexpr (IsSameType<T, fp8_e4m3fn_t>::value) { | ||
| 329 | + // fp8_e4m3 | ||
| 330 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 331 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 332 | + AscendC::Reg::Cast< | ||
| 333 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E4M3_TO_FP32>( | ||
| 334 | + vregFloatX, vregX, mask); | ||
| 335 | + } else if constexpr (IsSameType<T, int8_t>::value) { | ||
| 336 | + // int8 | ||
| 337 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 338 | + vregX, xLocalAddr + i * VL + j * xLocalOffset); | ||
| 339 | + AscendC::Reg::Cast< | ||
| 340 | + half, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 341 | + vregHalfX, vregX, mask); | ||
| 342 | + AscendC::Reg::Cast< | ||
| 343 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 344 | + vregFloatX, vregHalfX, mask); | ||
| 345 | + } else if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 346 | + // int4 | ||
| 347 | + AscendC::Reg::RegTensor<half> vregTmpX; | ||
| 348 | + AscendC::Reg::RegTensor<uint16_t> vregTmpU16X; | ||
| 349 | + AscendC::Reg::DataCopy<xCopyDtype, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 350 | + vregX, xLocalAddr + i * HalfVL + j * xLocalOffset); | ||
| 351 | + AscendC::Reg::Cast< | ||
| 352 | + half, int4x2_t, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 353 | + (AscendC::Reg::RegTensor<half>&)vregTmpU16X, | ||
| 354 | + (AscendC::Reg::RegTensor<int4x2_t>&)vregX, mask); | ||
| 355 | + AscendC::Reg::UnPack((AscendC::Reg::RegTensor<uint32_t>&)vregTmpX, vregTmpU16X); | ||
| 356 | + AscendC::Reg::Cast< | ||
| 357 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 358 | + vregFloatX, vregTmpX, mask); | ||
| 359 | + } | ||
| 360 | + | ||
| 361 | + // ld and cast for scale | ||
| 362 | + if constexpr (IsSameType<T1, float>::value) { | ||
| 363 | + // fp32 | ||
| 364 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_BRC_B32>( | ||
| 365 | + vregFloatS, scaleLocalAddr + j); | ||
| 366 | + } else if constexpr (IsSameType<T1, bfloat16_t>::value) { | ||
| 367 | + // bf16 | ||
| 368 | + AscendC::Reg::DataCopy<T1, AscendC::Reg::LoadDist::DIST_BRC_B16>(vregS, scaleLocalAddr + j); | ||
| 369 | + AscendC::Reg::Cast< | ||
| 370 | + float, T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 371 | + vregFloatS, vregS, mask); | ||
| 372 | + } | ||
| 373 | + | ||
| 374 | + // ld and cast for offset | ||
| 375 | + if constexpr (IsSameType<T2, float>::value) { | ||
| 376 | + // fp32 | ||
| 377 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_BRC_B32>( | ||
| 378 | + vregFloatO, offsetLocalAddr + j); | ||
| 379 | + } else if constexpr (IsSameType<T2, bfloat16_t>::value) { | ||
| 380 | + // bf16 | ||
| 381 | + AscendC::Reg::DataCopy<T2, AscendC::Reg::LoadDist::DIST_BRC_B16>(vregO, offsetLocalAddr + j); | ||
| 382 | + AscendC::Reg::Cast< | ||
| 383 | + float, T2, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 384 | + vregFloatO, vregO, mask); | ||
| 385 | + } | ||
| 386 | + | ||
| 387 | + // compute | ||
| 388 | + AscendC::Reg::Add<float, AscendC::Reg::MaskMergeMode::ZEROING>(vregTmp1, vregFloatX, vregFloatO, mask); | ||
| 389 | + if constexpr (SqrtMode == TPL_SQRT_MODE) { | ||
| 390 | + AscendC::Reg::Mul(vregFloatS, vregFloatS, vregFloatS, mask); | ||
| 391 | + } | ||
| 392 | + AscendC::Reg::Mul(vregFloatY, vregTmp1, vregFloatS, mask); | ||
| 393 | + | ||
| 394 | + // cast and sd for y | ||
| 395 | + if constexpr (IsSameType<U, half>::value) { | ||
| 396 | + // fp16 | ||
| 397 | + AscendC::Reg::Cast< | ||
| 398 | + half, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_HALF>( | ||
| 399 | + vregY, vregFloatY, mask); | ||
| 400 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 401 | + outLocalAddr + i * VL + j * xLocalOffset, vregY, mask); | ||
| 402 | + } else if constexpr (IsSameType<U, bfloat16_t>::value) { | ||
| 403 | + // bf16 | ||
| 404 | + AscendC::Reg::Cast< | ||
| 405 | + U, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_BF16>( | ||
| 406 | + vregY, vregFloatY, mask); | ||
| 407 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 408 | + outLocalAddr + i * VL + j * xLocalOffset, vregY, mask); | ||
| 409 | + } | ||
| 410 | + } | ||
| 411 | + } | ||
| 412 | + } | ||
| 413 | + inQueueX_.FreeTensor(xLocal); | ||
| 414 | + outQueueY_.EnQue(outLocal); | ||
| 415 | +} | ||
| 416 | + | ||
| 417 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 418 | +__aicore__ inline void AscendAntiQuantV2PerHeadRegbase<T, T1, T2, U, SqrtMode>::GetOutCopyParams( | ||
| 419 | + const AscendAntiQuantV2TilingData* tilingData, int64_t yN, int64_t yLen, int64_t lastDimLen, | ||
| 420 | + DataCopyExtParams& copyParams) | ||
| 421 | +{ | ||
| 422 | + copyParams.blockCount = yN; | ||
| 423 | + copyParams.blockLen = yLen * sizeof(U); | ||
| 424 | + if (tilingData->baseLen > yLen) { | ||
| 425 | + copyParams.srcStride = (tilingData->baseLen - yLen) * sizeof(U) / this->BLOCK_SIZE; | ||
| 426 | + } else { | ||
| 427 | + copyParams.srcStride = 0; | ||
| 428 | + } | ||
| 429 | + if (lastDimLen > yLen) { | ||
| 430 | + copyParams.dstStride = (lastDimLen - yLen) * sizeof(U); | ||
| 431 | + } else { | ||
| 432 | + copyParams.dstStride = 0; | ||
| 433 | + } | ||
| 434 | +} | ||
| 435 | + | ||
| 436 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 437 | +__aicore__ inline void AscendAntiQuantV2PerHeadRegbase<T, T1, T2, U, SqrtMode>::CopyOutY( | ||
| 438 | + int64_t yN, int64_t yLen, int64_t yOutOffset) | ||
| 439 | +{ | ||
| 440 | + LocalTensor<U> outLocal = outQueueY_.DeQue<U>(); | ||
| 441 | + DataCopyExtParams copyParams; | ||
| 442 | + GetOutCopyParams(tilingData_, yN, yLen, tilingData_->dim2, copyParams); | ||
| 443 | + DataCopyPad<U>(yGm_[yOutOffset], outLocal, copyParams); | ||
| 444 | + outQueueY_.FreeTensor(outLocal); | ||
| 445 | +} | ||
| 446 | +} // namespace AscendAntiQuantV2 | ||
| 447 | + | ||
Aquant/ascend_anti_quant_v2/op_kernel/arch35/ascend_anti_quant_v2_per_tensor_no_offset_regbase.h+280-0
| @@ -0,0 +1,280 @@ | |||
| 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 ascend_anti_quant_v2_per_tensor_no_offset_regbase.h | ||
| 13 | + * \brief ascendantiquantv2 kernel | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +namespace AscendAntiQuantV2 { | ||
| 26 | +using namespace AscendC; | ||
| 27 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 28 | +class AscendAntiQuantV2PerTensorNoOffsetRegbase : public AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode> { | ||
| 29 | +public: | ||
| 30 | + __aicore__ inline AscendAntiQuantV2PerTensorNoOffsetRegbase(const AscendAntiQuantV2TilingData* tilingData) | ||
| 31 | + : tilingData_(tilingData){}; | ||
| 32 | + __aicore__ inline void Init(GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y); | ||
| 33 | + __aicore__ inline void Process(); | ||
| 34 | + | ||
| 35 | +private: | ||
| 36 | + __aicore__ inline void CopyXAndCompute(int64_t dataCount, int64_t offset, LocalTensor<T1>& sLocal); | ||
| 37 | + __aicore__ inline void CopyInScale(); | ||
| 38 | + __aicore__ inline void CopyInX(int64_t xLen, int64_t xInOffset); | ||
| 39 | + __aicore__ inline void CopyOutY(int64_t yLen, int64_t yOutOffset); | ||
| 40 | + __aicore__ inline void Compute(int64_t dataCount, LocalTensor<T1>& sLocal); | ||
| 41 | + | ||
| 42 | +private: | ||
| 43 | + using xCopyDtype = std::conditional_t<IsSameType<T, int4b_t>::value, uint8_t, T>; | ||
| 44 | + constexpr static int32_t bufferNum_ = 2; | ||
| 45 | + TPipe pipe_; | ||
| 46 | + TQue<QuePosition::VECIN, bufferNum_> inQueueX_; | ||
| 47 | + TQue<QuePosition::VECIN, bufferNum_> inQueueScale_; | ||
| 48 | + TQue<QuePosition::VECOUT, bufferNum_> outQueueY_; | ||
| 49 | + GlobalTensor<uint8_t> xGm_; | ||
| 50 | + GlobalTensor<T1> scaleGm_; | ||
| 51 | + GlobalTensor<U> yGm_; | ||
| 52 | + | ||
| 53 | + const AscendAntiQuantV2TilingData* tilingData_; | ||
| 54 | + int32_t blockIdx_ = 0; | ||
| 55 | + int64_t gmXOffset_ = 0; | ||
| 56 | + int64_t blockN_ = 1; | ||
| 57 | + int64_t blockLen_ = 1; | ||
| 58 | +}; | ||
| 59 | + | ||
| 60 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 61 | +__aicore__ inline void AscendAntiQuantV2PerTensorNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Init( | ||
| 62 | + GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y) | ||
| 63 | +{ | ||
| 64 | + blockIdx_ = GetBlockIdx(); | ||
| 65 | + xGm_.SetGlobalBuffer(reinterpret_cast<__gm__ uint8_t*>(x)); | ||
| 66 | + scaleGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T1*>(scale)); | ||
| 67 | + yGm_.SetGlobalBuffer(reinterpret_cast<__gm__ U*>(y)); | ||
| 68 | + | ||
| 69 | + blockN_ = tilingData_->dim0; | ||
| 70 | + if (blockIdx_ == tilingData_->numCore - 1) { | ||
| 71 | + blockLen_ = tilingData_->blockTailFactor; | ||
| 72 | + } else { | ||
| 73 | + blockLen_ = tilingData_->blockFactor; | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + // calc n size to alloc queue | ||
| 77 | + pipe_.InitBuffer(inQueueX_, bufferNum_, tilingData_->baseN * tilingData_->baseLen * sizeof(xCopyDtype)); | ||
| 78 | + pipe_.InitBuffer(inQueueScale_, bufferNum_, this->BLOCK_SIZE); | ||
| 79 | + | ||
| 80 | + pipe_.InitBuffer(outQueueY_, bufferNum_, tilingData_->baseN * tilingData_->baseLen * sizeof(U)); | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 84 | +__aicore__ inline void AscendAntiQuantV2PerTensorNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Process() | ||
| 85 | +{ | ||
| 86 | + if (blockIdx_ >= tilingData_->numCore) { | ||
| 87 | + return; | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + gmXOffset_ = blockIdx_ * tilingData_->blockFactor; | ||
| 91 | + | ||
| 92 | + // main loop with column, for scale and offset only need copy once | ||
| 93 | + int64_t lenLoopNum = blockLen_ / tilingData_->baseLen; | ||
| 94 | + int64_t lenLoopTail = blockLen_ % tilingData_->baseLen; | ||
| 95 | + CopyInScale(); | ||
| 96 | + LocalTensor<T1> sLocal = inQueueScale_.DeQue<T1>(); | ||
| 97 | + for (int64_t i = 0; i < lenLoopNum; ++i) { | ||
| 98 | + CopyXAndCompute(tilingData_->baseLen, gmXOffset_ + i * tilingData_->baseLen, sLocal); | ||
| 99 | + } | ||
| 100 | + if (lenLoopTail != 0) { | ||
| 101 | + CopyXAndCompute(lenLoopTail, gmXOffset_ + lenLoopNum * tilingData_->baseLen, sLocal); | ||
| 102 | + } | ||
| 103 | + inQueueScale_.FreeTensor(sLocal); | ||
| 104 | +} | ||
| 105 | + | ||
| 106 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 107 | +__aicore__ inline void AscendAntiQuantV2PerTensorNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyInScale() | ||
| 108 | +{ | ||
| 109 | + DataCopyExtParams copyParams; | ||
| 110 | + copyParams.blockCount = 1; | ||
| 111 | + copyParams.blockLen = sizeof(T1); | ||
| 112 | + copyParams.dstStride = 0; | ||
| 113 | + copyParams.srcStride = 0; | ||
| 114 | + copyParams.rsv = 0; | ||
| 115 | + LocalTensor<T1> sLocal = inQueueScale_.AllocTensor<T1>(); | ||
| 116 | + DataCopyPad(sLocal, scaleGm_, copyParams, {false, 0, 0, 0}); | ||
| 117 | + inQueueScale_.EnQue(sLocal); | ||
| 118 | +} | ||
| 119 | + | ||
| 120 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 121 | +__aicore__ inline void AscendAntiQuantV2PerTensorNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyXAndCompute( | ||
| 122 | + int64_t dataCount, int64_t offset, LocalTensor<T1>& sLocal) | ||
| 123 | +{ | ||
| 124 | + CopyInX(dataCount, offset); | ||
| 125 | + Compute(dataCount, sLocal); | ||
| 126 | + CopyOutY(dataCount, offset); | ||
| 127 | +} | ||
| 128 | + | ||
| 129 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 130 | +__aicore__ inline void AscendAntiQuantV2PerTensorNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyInX( | ||
| 131 | + int64_t xLen, int64_t xInOffset) | ||
| 132 | +{ | ||
| 133 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 134 | + xInOffset = xInOffset >> 1; | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + LocalTensor<uint8_t> xLocal = inQueueX_.AllocTensor<uint8_t>(); | ||
| 138 | + DataCopyExtParams copyParams; | ||
| 139 | + DataCopyPadExtParams<uint8_t> padParams = {false, 0, 0, 0}; | ||
| 140 | + this->GetXInCopyParams(tilingData_->dim1, tilingData_->baseLen, tilingData_->baseN, xLen, copyParams); | ||
| 141 | + DataCopyPad<uint8_t>(xLocal, xGm_[xInOffset], copyParams, padParams); | ||
| 142 | + inQueueX_.EnQue(xLocal); | ||
| 143 | +} | ||
| 144 | + | ||
| 145 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 146 | +__aicore__ inline void AscendAntiQuantV2PerTensorNoOffsetRegbase<T, T1, T2, U, SqrtMode>::Compute( | ||
| 147 | + int64_t dataCount, LocalTensor<T1>& sLocal) | ||
| 148 | +{ | ||
| 149 | + LocalTensor<xCopyDtype> xLocal = inQueueX_.DeQue<xCopyDtype>(); | ||
| 150 | + LocalTensor<U> outLocal = outQueueY_.AllocTensor<U>(); | ||
| 151 | + | ||
| 152 | + __local_mem__ xCopyDtype* xLocalAddr = (__local_mem__ xCopyDtype*)xLocal.GetPhyAddr(); | ||
| 153 | + __local_mem__ T1* scaleLocalAddr = (__local_mem__ T1*)sLocal.GetPhyAddr(); | ||
| 154 | + __local_mem__ U* outLocalAddr = (__local_mem__ U*)outLocal.GetPhyAddr(); | ||
| 155 | + | ||
| 156 | + uint16_t VL = AscendC::VECTOR_REG_WIDTH / sizeof(float); | ||
| 157 | + uint16_t HalfVL = VL / 2; | ||
| 158 | + uint16_t vfLoopNum = (dataCount + VL - 1) / VL; | ||
| 159 | + | ||
| 160 | + // has offset | ||
| 161 | + __VEC_SCOPE__ | ||
| 162 | + { | ||
| 163 | + // x: int4, int8, hifp8, fp8_e5m2, fp8_e4m3 | ||
| 164 | + AscendC::Reg::RegTensor<xCopyDtype> vregX; | ||
| 165 | + AscendC::Reg::RegTensor<half> vregHalfX; | ||
| 166 | + AscendC::Reg::RegTensor<float> vregFloatX; | ||
| 167 | + // scales: fp32, bf16 | ||
| 168 | + AscendC::Reg::RegTensor<T1> vregS; | ||
| 169 | + AscendC::Reg::RegTensor<float> vregFloatS; | ||
| 170 | + // y: fp16, bf16 | ||
| 171 | + AscendC::Reg::RegTensor<float> vregFloatY; | ||
| 172 | + AscendC::Reg::RegTensor<U> vregY; | ||
| 173 | + | ||
| 174 | + AscendC::Reg::MaskReg mask; | ||
| 175 | + | ||
| 176 | + mask = AscendC::Reg::CreateMask<float>(); | ||
| 177 | + uint32_t count = dataCount; | ||
| 178 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 179 | + mask = AscendC::Reg::UpdateMask<float>(count); | ||
| 180 | + // ld and cast for x | ||
| 181 | + if constexpr (IsSameType<T, hifloat8_t>::value) { | ||
| 182 | + // hifp8 | ||
| 183 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 184 | + vregX, xLocalAddr + i * VL); | ||
| 185 | + AscendC::Reg::Cast< | ||
| 186 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HIFP8_TO_FP32>( | ||
| 187 | + vregFloatX, vregX, mask); | ||
| 188 | + } else if constexpr (IsSameType<T, fp8_e5m2_t>::value) { | ||
| 189 | + // fp8_e5m2 | ||
| 190 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 191 | + vregX, xLocalAddr + i * VL); | ||
| 192 | + AscendC::Reg::Cast< | ||
| 193 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E5M2_TO_FP32>( | ||
| 194 | + vregFloatX, vregX, mask); | ||
| 195 | + } else if constexpr (IsSameType<T, fp8_e4m3fn_t>::value) { | ||
| 196 | + // fp8_e4m3 | ||
| 197 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 198 | + vregX, xLocalAddr + i * VL); | ||
| 199 | + AscendC::Reg::Cast< | ||
| 200 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E4M3_TO_FP32>( | ||
| 201 | + vregFloatX, vregX, mask); | ||
| 202 | + } else if constexpr (IsSameType<T, int8_t>::value) { | ||
| 203 | + // int8 | ||
| 204 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 205 | + vregX, xLocalAddr + i * VL); | ||
| 206 | + AscendC::Reg::Cast< | ||
| 207 | + half, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 208 | + vregHalfX, vregX, mask); | ||
| 209 | + AscendC::Reg::Cast< | ||
| 210 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 211 | + vregFloatX, vregHalfX, mask); | ||
| 212 | + } else if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 213 | + // int4 | ||
| 214 | + AscendC::Reg::RegTensor<half> vregTmpX; | ||
| 215 | + AscendC::Reg::RegTensor<uint16_t> vregTmpU16X; | ||
| 216 | + AscendC::Reg::DataCopy<xCopyDtype, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 217 | + vregX, xLocalAddr + i * HalfVL); | ||
| 218 | + AscendC::Reg::Cast< | ||
| 219 | + half, int4x2_t, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 220 | + (AscendC::Reg::RegTensor<half>&)vregTmpU16X, | ||
| 221 | + (AscendC::Reg::RegTensor<int4x2_t>&)vregX, mask); | ||
| 222 | + AscendC::Reg::UnPack((AscendC::Reg::RegTensor<uint32_t>&)vregTmpX, vregTmpU16X); | ||
| 223 | + AscendC::Reg::Cast< | ||
| 224 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 225 | + vregFloatX, vregTmpX, mask); | ||
| 226 | + } | ||
| 227 | + | ||
| 228 | + // ld and cast for scale | ||
| 229 | + if constexpr (IsSameType<T1, float>::value) { | ||
| 230 | + // fp32 | ||
| 231 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_BRC_B32>( | ||
| 232 | + vregFloatS, scaleLocalAddr); | ||
| 233 | + } else if constexpr (IsSameType<T1, bfloat16_t>::value) { | ||
| 234 | + // bf16 | ||
| 235 | + AscendC::Reg::DataCopy<T1, AscendC::Reg::LoadDist::DIST_BRC_B16>(vregS, scaleLocalAddr); | ||
| 236 | + AscendC::Reg::Cast< | ||
| 237 | + float, T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 238 | + vregFloatS, vregS, mask); | ||
| 239 | + } | ||
| 240 | + | ||
| 241 | + // compute | ||
| 242 | + if constexpr (SqrtMode == TPL_SQRT_MODE) { | ||
| 243 | + AscendC::Reg::Mul(vregFloatS, vregFloatS, vregFloatS, mask); | ||
| 244 | + } | ||
| 245 | + AscendC::Reg::Mul(vregFloatY, vregFloatX, vregFloatS, mask); | ||
| 246 | + | ||
| 247 | + // cast and sd for y | ||
| 248 | + if constexpr (IsSameType<U, half>::value) { | ||
| 249 | + // fp16 | ||
| 250 | + AscendC::Reg::Cast< | ||
| 251 | + half, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_HALF>( | ||
| 252 | + vregY, vregFloatY, mask); | ||
| 253 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 254 | + outLocalAddr + i * VL, vregY, mask); | ||
| 255 | + } else if constexpr (IsSameType<U, bfloat16_t>::value) { | ||
| 256 | + // bf16 | ||
| 257 | + AscendC::Reg::Cast< | ||
| 258 | + U, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_BF16>( | ||
| 259 | + vregY, vregFloatY, mask); | ||
| 260 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 261 | + outLocalAddr + i * VL, vregY, mask); | ||
| 262 | + } | ||
| 263 | + } | ||
| 264 | + } | ||
| 265 | + inQueueX_.FreeTensor(xLocal); | ||
| 266 | + outQueueY_.EnQue(outLocal); | ||
| 267 | +} | ||
| 268 | + | ||
| 269 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 270 | +__aicore__ inline void AscendAntiQuantV2PerTensorNoOffsetRegbase<T, T1, T2, U, SqrtMode>::CopyOutY( | ||
| 271 | + int64_t yLen, int64_t yOutOffset) | ||
| 272 | +{ | ||
| 273 | + LocalTensor<U> outLocal = outQueueY_.DeQue<U>(); | ||
| 274 | + DataCopyExtParams copyParams; | ||
| 275 | + this->GetOutCopyParams(tilingData_->dim1, tilingData_->baseLen, tilingData_->baseN, yLen, copyParams); | ||
| 276 | + DataCopyPad<U>(yGm_[yOutOffset], outLocal, copyParams); | ||
| 277 | + outQueueY_.FreeTensor(outLocal); | ||
| 278 | +} | ||
| 279 | +} // namespace AscendAntiQuantV2 | ||
| 280 | + | ||
| @@ -0,0 +1,321 @@ | |||
| 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 ascend_anti_quant_v2_per_tensor_regbase.h | ||
| 13 | + * \brief ascendantiquantv2 kernel | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +namespace AscendAntiQuantV2 { | ||
| 26 | +using namespace AscendC; | ||
| 27 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 28 | +class AscendAntiQuantV2PerTensorRegbase : public AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode> { | ||
| 29 | +public: | ||
| 30 | + __aicore__ inline AscendAntiQuantV2PerTensorRegbase(const AscendAntiQuantV2TilingData* tilingData) | ||
| 31 | + : tilingData_(tilingData){}; | ||
| 32 | + __aicore__ inline void Init(GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y); | ||
| 33 | + __aicore__ inline void Process(); | ||
| 34 | + | ||
| 35 | +private: | ||
| 36 | + __aicore__ inline void CopyXAndCompute(int64_t dataCount, int64_t offset, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal); | ||
| 37 | + __aicore__ inline void CopyInScale(); | ||
| 38 | + __aicore__ inline void CopyInOffset(); | ||
| 39 | + __aicore__ inline void CopyInX(int64_t xLen, int64_t xInOffset); | ||
| 40 | + __aicore__ inline void CopyOutY(int64_t yLen, int64_t yOutOffset); | ||
| 41 | + __aicore__ inline void Compute(int64_t dataCount, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal); | ||
| 42 | + | ||
| 43 | +private: | ||
| 44 | + using xCopyDtype = std::conditional_t<IsSameType<T, int4b_t>::value, uint8_t, T>; | ||
| 45 | + constexpr static int32_t bufferNum_ = 2; | ||
| 46 | + TPipe pipe_; | ||
| 47 | + TQue<QuePosition::VECIN, bufferNum_> inQueueX_; | ||
| 48 | + TQue<QuePosition::VECIN, bufferNum_> inQueueScale_; | ||
| 49 | + TQue<QuePosition::VECIN, bufferNum_> inQueueOffset_; | ||
| 50 | + TQue<QuePosition::VECOUT, bufferNum_> outQueueY_; | ||
| 51 | + GlobalTensor<uint8_t> xGm_; | ||
| 52 | + GlobalTensor<T1> scaleGm_; | ||
| 53 | + GlobalTensor<T2> offsetGm_; | ||
| 54 | + GlobalTensor<U> yGm_; | ||
| 55 | + | ||
| 56 | + const AscendAntiQuantV2TilingData* tilingData_; | ||
| 57 | + int32_t blockIdx_ = 0; | ||
| 58 | + int64_t gmXOffset_ = 0; | ||
| 59 | + int64_t blockN_ = 1; | ||
| 60 | + int64_t blockLen_ = 1; | ||
| 61 | +}; | ||
| 62 | + | ||
| 63 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 64 | +__aicore__ inline void AscendAntiQuantV2PerTensorRegbase<T, T1, T2, U, SqrtMode>::Init( | ||
| 65 | + GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y) | ||
| 66 | +{ | ||
| 67 | + blockIdx_ = GetBlockIdx(); | ||
| 68 | + xGm_.SetGlobalBuffer(reinterpret_cast<__gm__ uint8_t*>(x)); | ||
| 69 | + scaleGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T1*>(scale)); | ||
| 70 | + offsetGm_.SetGlobalBuffer(reinterpret_cast<__gm__ T2*>(offset)); | ||
| 71 | + yGm_.SetGlobalBuffer(reinterpret_cast<__gm__ U*>(y)); | ||
| 72 | + | ||
| 73 | + blockN_ = tilingData_->dim0; | ||
| 74 | + if (blockIdx_ == tilingData_->numCore - 1) { | ||
| 75 | + blockLen_ = tilingData_->blockTailFactor; | ||
| 76 | + } else { | ||
| 77 | + blockLen_ = tilingData_->blockFactor; | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + // calc n size to alloc queue | ||
| 81 | + pipe_.InitBuffer(inQueueX_, bufferNum_, tilingData_->baseN * tilingData_->baseLen * sizeof(xCopyDtype)); | ||
| 82 | + pipe_.InitBuffer(inQueueScale_, bufferNum_, this->BLOCK_SIZE); | ||
| 83 | + pipe_.InitBuffer(inQueueOffset_, bufferNum_, this->BLOCK_SIZE); | ||
| 84 | + | ||
| 85 | + pipe_.InitBuffer(outQueueY_, bufferNum_, tilingData_->baseN * tilingData_->baseLen * sizeof(U)); | ||
| 86 | +} | ||
| 87 | + | ||
| 88 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 89 | +__aicore__ inline void AscendAntiQuantV2PerTensorRegbase<T, T1, T2, U, SqrtMode>::Process() | ||
| 90 | +{ | ||
| 91 | + if (blockIdx_ >= tilingData_->numCore) { | ||
| 92 | + return; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + gmXOffset_ = blockIdx_ * tilingData_->blockFactor; | ||
| 96 | + | ||
| 97 | + // main loop with column, for scale and offset only need copy once | ||
| 98 | + int64_t lenLoopNum = blockLen_ / tilingData_->baseLen; | ||
| 99 | + int64_t lenLoopTail = blockLen_ % tilingData_->baseLen; | ||
| 100 | + CopyInScale(); | ||
| 101 | + CopyInOffset(); | ||
| 102 | + LocalTensor<T1> sLocal = inQueueScale_.DeQue<T1>(); | ||
| 103 | + LocalTensor<T2> oLocal = inQueueOffset_.DeQue<T2>(); | ||
| 104 | + for (int64_t i = 0; i < lenLoopNum; ++i) { | ||
| 105 | + CopyXAndCompute(tilingData_->baseLen, gmXOffset_ + i * tilingData_->baseLen, sLocal, oLocal); | ||
| 106 | + } | ||
| 107 | + if (lenLoopTail != 0) { | ||
| 108 | + CopyXAndCompute(lenLoopTail, gmXOffset_ + lenLoopNum * tilingData_->baseLen, sLocal, oLocal); | ||
| 109 | + } | ||
| 110 | + inQueueScale_.FreeTensor(sLocal); | ||
| 111 | + inQueueOffset_.FreeTensor(oLocal); | ||
| 112 | +} | ||
| 113 | + | ||
| 114 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 115 | +__aicore__ inline void AscendAntiQuantV2PerTensorRegbase<T, T1, T2, U, SqrtMode>::CopyInScale() | ||
| 116 | +{ | ||
| 117 | + DataCopyExtParams copyParams; | ||
| 118 | + copyParams.blockCount = 1; | ||
| 119 | + copyParams.blockLen = sizeof(T1); | ||
| 120 | + copyParams.dstStride = 0; | ||
| 121 | + copyParams.srcStride = 0; | ||
| 122 | + copyParams.rsv = 0; | ||
| 123 | + LocalTensor<T1> sLocal = inQueueScale_.AllocTensor<T1>(); | ||
| 124 | + DataCopyPad(sLocal, scaleGm_, copyParams, {false, 0, 0, 0}); | ||
| 125 | + inQueueScale_.EnQue(sLocal); | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 129 | +__aicore__ inline void AscendAntiQuantV2PerTensorRegbase<T, T1, T2, U, SqrtMode>::CopyInOffset() | ||
| 130 | +{ | ||
| 131 | + DataCopyExtParams copyParams; | ||
| 132 | + copyParams.blockCount = 1; | ||
| 133 | + copyParams.blockLen = sizeof(T2); | ||
| 134 | + copyParams.dstStride = 0; | ||
| 135 | + copyParams.srcStride = 0; | ||
| 136 | + copyParams.rsv = 0; | ||
| 137 | + LocalTensor<T2> oLocal = inQueueOffset_.AllocTensor<T2>(); | ||
| 138 | + DataCopyPad(oLocal, offsetGm_, copyParams, {false, 0, 0, 0}); | ||
| 139 | + inQueueOffset_.EnQue(oLocal); | ||
| 140 | +} | ||
| 141 | + | ||
| 142 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 143 | +__aicore__ inline void AscendAntiQuantV2PerTensorRegbase<T, T1, T2, U, SqrtMode>::CopyXAndCompute( | ||
| 144 | + int64_t dataCount, int64_t offset, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal) | ||
| 145 | +{ | ||
| 146 | + CopyInX(dataCount, offset); | ||
| 147 | + Compute(dataCount, sLocal, oLocal); | ||
| 148 | + CopyOutY(dataCount, offset); | ||
| 149 | +} | ||
| 150 | + | ||
| 151 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 152 | +__aicore__ inline void AscendAntiQuantV2PerTensorRegbase<T, T1, T2, U, SqrtMode>::CopyInX( | ||
| 153 | + int64_t xLen, int64_t xInOffset) | ||
| 154 | +{ | ||
| 155 | + if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 156 | + xInOffset = xInOffset >> 1; | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + LocalTensor<uint8_t> xLocal = inQueueX_.AllocTensor<uint8_t>(); | ||
| 160 | + DataCopyExtParams copyParams; | ||
| 161 | + DataCopyPadExtParams<uint8_t> padParams = {false, 0, 0, 0}; | ||
| 162 | + this->GetXInCopyParams(tilingData_->dim1, tilingData_->baseLen, tilingData_->baseN, xLen, copyParams); | ||
| 163 | + DataCopyPad<uint8_t>(xLocal, xGm_[xInOffset], copyParams, padParams); | ||
| 164 | + inQueueX_.EnQue(xLocal); | ||
| 165 | +} | ||
| 166 | + | ||
| 167 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 168 | +__aicore__ inline void AscendAntiQuantV2PerTensorRegbase<T, T1, T2, U, SqrtMode>::Compute( | ||
| 169 | + int64_t dataCount, LocalTensor<T1>& sLocal, LocalTensor<T2>& oLocal) | ||
| 170 | +{ | ||
| 171 | + LocalTensor<xCopyDtype> xLocal = inQueueX_.DeQue<xCopyDtype>(); | ||
| 172 | + LocalTensor<U> outLocal = outQueueY_.AllocTensor<U>(); | ||
| 173 | + | ||
| 174 | + __local_mem__ xCopyDtype* xLocalAddr = (__local_mem__ xCopyDtype*)xLocal.GetPhyAddr(); | ||
| 175 | + __local_mem__ T1* scaleLocalAddr = (__local_mem__ T1*)sLocal.GetPhyAddr(); | ||
| 176 | + __local_mem__ T2* offsetLocalAddr = (__local_mem__ T2*)oLocal.GetPhyAddr(); | ||
| 177 | + __local_mem__ U* outLocalAddr = (__local_mem__ U*)outLocal.GetPhyAddr(); | ||
| 178 | + | ||
| 179 | + uint16_t VL = AscendC::VECTOR_REG_WIDTH / sizeof(float); | ||
| 180 | + uint16_t HalfVL = VL / 2; | ||
| 181 | + uint16_t vfLoopNum = (dataCount + VL - 1) / VL; | ||
| 182 | + | ||
| 183 | + // has offset | ||
| 184 | + __VEC_SCOPE__ | ||
| 185 | + { | ||
| 186 | + // x: int4, int8, hifp8, fp8_e5m2, fp8_e4m3 | ||
| 187 | + AscendC::Reg::RegTensor<xCopyDtype> vregX; | ||
| 188 | + AscendC::Reg::RegTensor<half> vregHalfX; | ||
| 189 | + AscendC::Reg::RegTensor<float> vregFloatX; | ||
| 190 | + // scales: fp32, bf16 | ||
| 191 | + AscendC::Reg::RegTensor<T1> vregS; | ||
| 192 | + AscendC::Reg::RegTensor<float> vregFloatS; | ||
| 193 | + // offset: fp32, bf16 | ||
| 194 | + AscendC::Reg::RegTensor<T2> vregO; | ||
| 195 | + AscendC::Reg::RegTensor<float> vregFloatO; | ||
| 196 | + // y: fp16, bf16 | ||
| 197 | + AscendC::Reg::RegTensor<float> vregFloatY; | ||
| 198 | + AscendC::Reg::RegTensor<U> vregY; | ||
| 199 | + | ||
| 200 | + AscendC::Reg::RegTensor<float> vregTmp1; | ||
| 201 | + AscendC::Reg::MaskReg mask; | ||
| 202 | + | ||
| 203 | + mask = AscendC::Reg::CreateMask<float>(); | ||
| 204 | + uint32_t count = dataCount; | ||
| 205 | + for (uint16_t i = 0; i < vfLoopNum; i++) { | ||
| 206 | + mask = AscendC::Reg::UpdateMask<float>(count); | ||
| 207 | + // ld and cast for x | ||
| 208 | + if constexpr (IsSameType<T, hifloat8_t>::value) { | ||
| 209 | + // hifp8 | ||
| 210 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 211 | + vregX, xLocalAddr + i * VL); | ||
| 212 | + AscendC::Reg::Cast< | ||
| 213 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HIFP8_TO_FP32>( | ||
| 214 | + vregFloatX, vregX, mask); | ||
| 215 | + } else if constexpr (IsSameType<T, fp8_e5m2_t>::value) { | ||
| 216 | + // fp8_e5m2 | ||
| 217 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 218 | + vregX, xLocalAddr + i * VL); | ||
| 219 | + AscendC::Reg::Cast< | ||
| 220 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E5M2_TO_FP32>( | ||
| 221 | + vregFloatX, vregX, mask); | ||
| 222 | + } else if constexpr (IsSameType<T, fp8_e4m3fn_t>::value) { | ||
| 223 | + // fp8_e4m3 | ||
| 224 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 225 | + vregX, xLocalAddr + i * VL); | ||
| 226 | + AscendC::Reg::Cast< | ||
| 227 | + float, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP8E4M3_TO_FP32>( | ||
| 228 | + vregFloatX, vregX, mask); | ||
| 229 | + } else if constexpr (IsSameType<T, int8_t>::value) { | ||
| 230 | + // int8 | ||
| 231 | + AscendC::Reg::DataCopy<T, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 232 | + vregX, xLocalAddr + i * VL); | ||
| 233 | + AscendC::Reg::Cast< | ||
| 234 | + half, T, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 235 | + vregHalfX, vregX, mask); | ||
| 236 | + AscendC::Reg::Cast< | ||
| 237 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 238 | + vregFloatX, vregHalfX, mask); | ||
| 239 | + } else if constexpr (IsSameType<T, int4b_t>::value) { | ||
| 240 | + // int4 | ||
| 241 | + AscendC::Reg::RegTensor<half> vregTmpX; | ||
| 242 | + AscendC::Reg::RegTensor<uint16_t> vregTmpU16X; | ||
| 243 | + AscendC::Reg::DataCopy<xCopyDtype, AscendC::Reg::LoadDist::DIST_UNPACK4_B8>( | ||
| 244 | + vregX, xLocalAddr + i * HalfVL); | ||
| 245 | + AscendC::Reg::Cast< | ||
| 246 | + half, int4x2_t, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_INT8_TO_HALF>( | ||
| 247 | + (AscendC::Reg::RegTensor<half>&)vregTmpU16X, | ||
| 248 | + (AscendC::Reg::RegTensor<int4x2_t>&)vregX, mask); | ||
| 249 | + AscendC::Reg::UnPack((AscendC::Reg::RegTensor<uint32_t>&)vregTmpX, vregTmpU16X); | ||
| 250 | + AscendC::Reg::Cast< | ||
| 251 | + float, half, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_HALF_TO_FP32>( | ||
| 252 | + vregFloatX, vregTmpX, mask); | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | + // ld and cast for scale | ||
| 256 | + if constexpr (IsSameType<T1, float>::value) { | ||
| 257 | + // fp32 | ||
| 258 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_BRC_B32>( | ||
| 259 | + vregFloatS, scaleLocalAddr); | ||
| 260 | + } else if constexpr (IsSameType<T1, bfloat16_t>::value) { | ||
| 261 | + // bf16 | ||
| 262 | + AscendC::Reg::DataCopy<T1, AscendC::Reg::LoadDist::DIST_BRC_B16>(vregS, scaleLocalAddr); | ||
| 263 | + AscendC::Reg::Cast< | ||
| 264 | + float, T1, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 265 | + vregFloatS, vregS, mask); | ||
| 266 | + } | ||
| 267 | + | ||
| 268 | + // ld and cast for offset | ||
| 269 | + if constexpr (IsSameType<T2, float>::value) { | ||
| 270 | + // fp32 | ||
| 271 | + AscendC::Reg::DataCopy<float, AscendC::Reg::LoadDist::DIST_BRC_B32>( | ||
| 272 | + vregFloatO, offsetLocalAddr); | ||
| 273 | + } else if constexpr (IsSameType<T2, bfloat16_t>::value) { | ||
| 274 | + // bf16 | ||
| 275 | + AscendC::Reg::DataCopy<T2, AscendC::Reg::LoadDist::DIST_BRC_B16>(vregO, offsetLocalAddr); | ||
| 276 | + AscendC::Reg::Cast< | ||
| 277 | + float, T2, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_BF16_TO_FP32>( | ||
| 278 | + vregFloatO, vregO, mask); | ||
| 279 | + } | ||
| 280 | + | ||
| 281 | + // compute | ||
| 282 | + AscendC::Reg::Add<float, AscendC::Reg::MaskMergeMode::ZEROING>(vregTmp1, vregFloatX, vregFloatO, mask); | ||
| 283 | + if constexpr (SqrtMode == TPL_SQRT_MODE) { | ||
| 284 | + AscendC::Reg::Mul(vregFloatS, vregFloatS, vregFloatS, mask); | ||
| 285 | + } | ||
| 286 | + AscendC::Reg::Mul(vregFloatY, vregTmp1, vregFloatS, mask); | ||
| 287 | + | ||
| 288 | + // cast and sd for y | ||
| 289 | + if constexpr (IsSameType<U, half>::value) { | ||
| 290 | + // fp16 | ||
| 291 | + AscendC::Reg::Cast< | ||
| 292 | + half, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_HALF>( | ||
| 293 | + vregY, vregFloatY, mask); | ||
| 294 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 295 | + outLocalAddr + i * VL, vregY, mask); | ||
| 296 | + } else if constexpr (IsSameType<U, bfloat16_t>::value) { | ||
| 297 | + // bf16 | ||
| 298 | + AscendC::Reg::Cast< | ||
| 299 | + U, float, AscendAntiQuantV2Base<T, T1, T2, U, SqrtMode>::CAST_TRAIT_FP32_TO_BF16>( | ||
| 300 | + vregY, vregFloatY, mask); | ||
| 301 | + AscendC::Reg::DataCopy<U, AscendC::Reg::StoreDist::DIST_PACK_B32>( | ||
| 302 | + outLocalAddr + i * VL, vregY, mask); | ||
| 303 | + } | ||
| 304 | + } | ||
| 305 | + } | ||
| 306 | + inQueueX_.FreeTensor(xLocal); | ||
| 307 | + outQueueY_.EnQue(outLocal); | ||
| 308 | +} | ||
| 309 | + | ||
| 310 | +template <typename T, typename T1, typename T2, typename U, uint64_t SqrtMode> | ||
| 311 | +__aicore__ inline void AscendAntiQuantV2PerTensorRegbase<T, T1, T2, U, SqrtMode>::CopyOutY( | ||
| 312 | + int64_t yLen, int64_t yOutOffset) | ||
| 313 | +{ | ||
| 314 | + LocalTensor<U> outLocal = outQueueY_.DeQue<U>(); | ||
| 315 | + DataCopyExtParams copyParams; | ||
| 316 | + this->GetOutCopyParams(tilingData_->dim1, tilingData_->baseLen, tilingData_->baseN, yLen, copyParams); | ||
| 317 | + DataCopyPad<U>(yGm_[yOutOffset], outLocal, copyParams); | ||
| 318 | + outQueueY_.FreeTensor(outLocal); | ||
| 319 | +} | ||
| 320 | +} // namespace AscendAntiQuantV2 | ||
| 321 | + | ||
| @@ -0,0 +1,48 @@ | |||
| 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 ascend_anti_quant_v2_struct.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + | ||
| 34 | +namespace AscendAntiQuantV2Op { | ||
| 35 | +ASCENDC_TPL_ARGS_DECL( | ||
| 36 | + AscendAntiQuantV2, | ||
| 37 | + ASCENDC_TPL_UINT_DECL(perMode, 3, ASCENDC_TPL_UI_LIST, TPL_PER_TENSOR, TPL_PER_CHANNEL, TPL_PER_HEAD, TPL_PER_CHANNEL_NDDMA, TPL_PER_HEAD_NDDMA), | ||
| 38 | + ASCENDC_TPL_UINT_DECL(zeroPointsType, 1, ASCENDC_TPL_UI_LIST, TPL_NO_OFFSET, TPL_HAS_OFFSET), | ||
| 39 | + ASCENDC_TPL_UINT_DECL(sqrtMode, 1, ASCENDC_TPL_UI_LIST, TPL_NO_SQRT_MODE, TPL_SQRT_MODE)); | ||
| 40 | + | ||
| 41 | +ASCENDC_TPL_SEL(ASCENDC_TPL_ARGS_SEL( | ||
| 42 | + ASCENDC_TPL_UINT_SEL(perMode, ASCENDC_TPL_UI_LIST, TPL_PER_TENSOR, TPL_PER_CHANNEL, TPL_PER_HEAD, TPL_PER_CHANNEL_NDDMA, TPL_PER_HEAD_NDDMA), | ||
| 43 | + ASCENDC_TPL_UINT_SEL(zeroPointsType, ASCENDC_TPL_UI_LIST, TPL_NO_OFFSET, TPL_HAS_OFFSET), | ||
| 44 | + ASCENDC_TPL_UINT_SEL(sqrtMode, ASCENDC_TPL_UI_LIST, TPL_NO_SQRT_MODE, TPL_SQRT_MODE))); | ||
| 45 | + | ||
| 46 | +} // namespace AscendAntiQuantV2Op | ||
| 47 | + | ||
| 48 | + | ||
| @@ -0,0 +1,35 @@ | |||
| 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 ascend_anti_quant_v2_tilingdata.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | +class AscendAntiQuantV2TilingData { | ||
| 20 | +public: | ||
| 21 | + int64_t numCore; | ||
| 22 | + int64_t blockAxis; | ||
| 23 | + int64_t dim0; | ||
| 24 | + int64_t dim1; | ||
| 25 | + int64_t dim2; | ||
| 26 | + int64_t blockUnion; | ||
| 27 | + int64_t blockFactor; | ||
| 28 | + int64_t blockTailFactor; | ||
| 29 | + int64_t baseN; | ||
| 30 | + int64_t baseLen; | ||
| 31 | + int64_t hasOffset; | ||
| 32 | + int64_t sqrtMode; | ||
| 33 | +}; | ||
| 34 | + | ||
| 35 | + | ||
| @@ -0,0 +1,100 @@ | |||
| 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 ascend_anti_quant_v2_apt.cpp | ||
| 13 | + * \brief ascend_anti_quant_v2 kernel enter | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | +using namespace AscendC; | ||
| 31 | +using namespace AscendAntiQuantV2; | ||
| 32 | +using namespace AscendAntiQuantV2Op; | ||
| 33 | + | ||
| 34 | +template <uint64_t perMode, uint64_t zeroPointsType, uint64_t sqrtMode> | ||
| 35 | +__global__ __aicore__ void ascend_anti_quant_v2( | ||
| 36 | + GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y, GM_ADDR workspace, GM_ADDR tiling) | ||
| 37 | +{ | ||
| 38 | + KERNEL_TASK_TYPE_DEFAULT(KERNEL_TYPE_AIV_ONLY); | ||
| 39 | + if constexpr (perMode == TPL_PER_TENSOR) { | ||
| 40 | + REGISTER_TILING_DEFAULT(AscendAntiQuantV2TilingData); | ||
| 41 | + GET_TILING_DATA_WITH_STRUCT(AscendAntiQuantV2TilingData, tilingData, tiling); | ||
| 42 | + if constexpr (zeroPointsType == TPL_HAS_OFFSET) { | ||
| 43 | + AscendAntiQuantV2PerTensorRegbase<DTYPE_X, DTYPE_SCALE, DTYPE_SCALE, DTYPE_Y, sqrtMode> op(&tilingData); | ||
| 44 | + op.Init(x, scale, offset, y); | ||
| 45 | + op.Process(); | ||
| 46 | + } else { | ||
| 47 | + AscendAntiQuantV2PerTensorNoOffsetRegbase<DTYPE_X, DTYPE_SCALE, DTYPE_SCALE, DTYPE_Y, sqrtMode> op(&tilingData); | ||
| 48 | + op.Init(x, scale, offset, y); | ||
| 49 | + op.Process(); | ||
| 50 | + } | ||
| 51 | + } else if constexpr (perMode == TPL_PER_CHANNEL) { | ||
| 52 | + REGISTER_TILING_DEFAULT(AscendAntiQuantV2TilingData); | ||
| 53 | + GET_TILING_DATA_WITH_STRUCT(AscendAntiQuantV2TilingData, tilingData, tiling); | ||
| 54 | + if constexpr (zeroPointsType == TPL_HAS_OFFSET) { | ||
| 55 | + AscendAntiQuantV2PerChannelRegbase<DTYPE_X, DTYPE_SCALE, DTYPE_SCALE, DTYPE_Y, sqrtMode> op(&tilingData); | ||
| 56 | + op.Init(x, scale, offset, y); | ||
| 57 | + op.Process(); | ||
| 58 | + } else { | ||
| 59 | + AscendAntiQuantV2PerChannelNoOffsetRegbase<DTYPE_X, DTYPE_SCALE, DTYPE_SCALE, DTYPE_Y, sqrtMode> op(&tilingData); | ||
| 60 | + op.Init(x, scale, offset, y); | ||
| 61 | + op.Process(); | ||
| 62 | + } | ||
| 63 | + } else if constexpr (perMode == TPL_PER_HEAD) { | ||
| 64 | + REGISTER_TILING_DEFAULT(AscendAntiQuantV2TilingData); | ||
| 65 | + GET_TILING_DATA_WITH_STRUCT(AscendAntiQuantV2TilingData, tilingData, tiling); | ||
| 66 | + if constexpr (zeroPointsType == TPL_HAS_OFFSET) { | ||
| 67 | + AscendAntiQuantV2PerHeadRegbase<DTYPE_X, DTYPE_SCALE, DTYPE_SCALE, DTYPE_Y, sqrtMode> op(&tilingData); | ||
| 68 | + op.Init(x, scale, offset, y); | ||
| 69 | + op.Process(); | ||
| 70 | + } else { | ||
| 71 | + AscendAntiQuantV2PerHeadNoOffsetRegbase<DTYPE_X, DTYPE_SCALE, DTYPE_SCALE, DTYPE_Y, sqrtMode> op(&tilingData); | ||
| 72 | + op.Init(x, scale, offset, y); | ||
| 73 | + op.Process(); | ||
| 74 | + } | ||
| 75 | + } else if constexpr (perMode == TPL_PER_CHANNEL_NDDMA) { | ||
| 76 | + REGISTER_TILING_DEFAULT(AscendAntiQuantV2TilingData); | ||
| 77 | + GET_TILING_DATA_WITH_STRUCT(AscendAntiQuantV2TilingData, tilingData, tiling); | ||
| 78 | + if constexpr (zeroPointsType == TPL_HAS_OFFSET) { | ||
| 79 | + AscendAntiQuantV2PerChannelNddmaRegbase<DTYPE_X, DTYPE_SCALE, DTYPE_SCALE, DTYPE_Y, sqrtMode> op(&tilingData); | ||
| 80 | + op.Init(x, scale, offset, y); | ||
| 81 | + op.Process(); | ||
| 82 | + } else { | ||
| 83 | + AscendAntiQuantV2PerChannelNddmaNoOffsetRegbase<DTYPE_X, DTYPE_SCALE, DTYPE_SCALE, DTYPE_Y, sqrtMode> op(&tilingData); | ||
| 84 | + op.Init(x, scale, offset, y); | ||
| 85 | + op.Process(); | ||
| 86 | + } | ||
| 87 | + } else if constexpr (perMode == TPL_PER_HEAD_NDDMA) { | ||
| 88 | + REGISTER_TILING_DEFAULT(AscendAntiQuantV2TilingData); | ||
| 89 | + GET_TILING_DATA_WITH_STRUCT(AscendAntiQuantV2TilingData, tilingData, tiling); | ||
| 90 | + if constexpr (zeroPointsType == TPL_HAS_OFFSET) { | ||
| 91 | + AscendAntiQuantV2PerHeadNddmaRegbase<DTYPE_X, DTYPE_SCALE, DTYPE_SCALE, DTYPE_Y, sqrtMode> op(&tilingData); | ||
| 92 | + op.Init(x, scale, offset, y); | ||
| 93 | + op.Process(); | ||
| 94 | + } else { | ||
| 95 | + AscendAntiQuantV2PerHeadNddmaNoOffsetRegbase<DTYPE_X, DTYPE_SCALE, DTYPE_SCALE, DTYPE_Y, sqrtMode> op(&tilingData); | ||
| 96 | + op.Init(x, scale, offset, y); | ||
| 97 | + op.Process(); | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | +} | ||
| @@ -7,7 +7,7 @@ | |||
| 7 | # See LICENSE in the root of the software repository for the full text of the License. | 7 | # See LICENSE in the root of the software repository for the full text of the License. |
| 8 | #/ | 8 | #/ |
| 9 | 9 | ||
| 10 | -message(STATUS "=== Debug: start ops.fusedop.ascend_quant_v2.tests.CMakeLists.txt ") | 10 | +message(STATUS "=== Debug: start ops.quant.ascend_anti_quant_v2.tests.CMakeLists.txt ") |
| 11 | file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | 11 | file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) |
| 12 | message(STATUS "=== Debug: CURRENT_DIRS =${CURRENT_DIRS} ") | 12 | message(STATUS "=== Debug: CURRENT_DIRS =${CURRENT_DIRS} ") |
| 13 | foreach(SUB_DIR ${CURRENT_DIRS}) | 13 | foreach(SUB_DIR ${CURRENT_DIRS}) |
| @@ -9,8 +9,8 @@ | |||
| 9 | 9 | ||
| 10 | file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | 10 | file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) |
| 11 | if(UT_TEST_ALL OR OP_HOST_UT) | 11 | if(UT_TEST_ALL OR OP_HOST_UT) |
| 12 | - #add_modules_ut_sources(HOSTNAME ${OP_TILING_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}) | 12 | + add_modules_ut_sources(HOSTNAME ${OP_TILING_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}) |
| 13 | - #add_modules_ut_sources(HOSTNAME ${OP_INFERSHAPE_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}) | 13 | + add_modules_ut_sources(HOSTNAME ${OP_INFERSHAPE_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}) |
| 14 | endif() | 14 | endif() |
| 15 | if(UT_TEST_ALL OR OP_API_UT) | 15 | if(UT_TEST_ALL OR OP_API_UT) |
| 16 | add_modules_ut_sources(HOSTNAME ${OP_API_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}) | 16 | add_modules_ut_sources(HOSTNAME ${OP_API_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}) |
| @@ -15,6 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | + | ||
| 18 | 19 | ||
| 19 | using namespace std; | 20 | using namespace std; |
| 20 | 21 | ||
| @@ -49,7 +50,7 @@ TEST_F(l2_ascend_anti_quant_test, ascend910B2_normal_1) | |||
| 49 | 50 | ||
| 50 | uint64_t workspace_size = 0; | 51 | uint64_t workspace_size = 0; |
| 51 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | 52 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); |
| 52 | - // EXPECT_EQ(aclRet, ACLNN_SUCCESS); | 53 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); |
| 53 | } | 54 | } |
| 54 | 55 | ||
| 55 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_normal_3) | 56 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_normal_3) |
| @@ -68,7 +69,7 @@ TEST_F(l2_ascend_anti_quant_test, ascend910B2_normal_3) | |||
| 68 | 69 | ||
| 69 | uint64_t workspace_size = 0; | 70 | uint64_t workspace_size = 0; |
| 70 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | 71 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); |
| 71 | - // EXPECT_EQ(aclRet, ACLNN_SUCCESS); | 72 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); |
| 72 | } | 73 | } |
| 73 | 74 | ||
| 74 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_normal_2) | 75 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_normal_2) |
| @@ -88,7 +89,7 @@ TEST_F(l2_ascend_anti_quant_test, ascend910B2_normal_2) | |||
| 88 | 89 | ||
| 89 | uint64_t workspace_size = 0; | 90 | uint64_t workspace_size = 0; |
| 90 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | 91 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); |
| 91 | - // EXPECT_EQ(aclRet, ACLNN_SUCCESS); | 92 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); |
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_normal_4) | 95 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_normal_4) |
| @@ -108,7 +109,7 @@ TEST_F(l2_ascend_anti_quant_test, ascend910B2_normal_4) | |||
| 108 | 109 | ||
| 109 | uint64_t workspace_size = 0; | 110 | uint64_t workspace_size = 0; |
| 110 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | 111 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); |
| 111 | - // EXPECT_EQ(aclRet, ACLNN_SUCCESS); | 112 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); |
| 112 | } | 113 | } |
| 113 | 114 | ||
| 114 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_normal_5) | 115 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_normal_5) |
| @@ -127,7 +128,7 @@ TEST_F(l2_ascend_anti_quant_test, ascend910B2_normal_5) | |||
| 127 | 128 | ||
| 128 | uint64_t workspace_size = 0; | 129 | uint64_t workspace_size = 0; |
| 129 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | 130 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); |
| 130 | - // EXPECT_EQ(aclRet, ACLNN_SUCCESS); | 131 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); |
| 131 | } | 132 | } |
| 132 | 133 | ||
| 133 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_int4) | 134 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_int4) |
| @@ -147,7 +148,7 @@ TEST_F(l2_ascend_anti_quant_test, ascend910B2_int4) | |||
| 147 | 148 | ||
| 148 | uint64_t workspace_size = 0; | 149 | uint64_t workspace_size = 0; |
| 149 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | 150 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); |
| 150 | - // EXPECT_EQ(aclRet, ACLNN_SUCCESS); | 151 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); |
| 151 | } | 152 | } |
| 152 | 153 | ||
| 153 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_int32) | 154 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_int32) |
| @@ -167,7 +168,7 @@ TEST_F(l2_ascend_anti_quant_test, ascend910B2_int32) | |||
| 167 | 168 | ||
| 168 | uint64_t workspace_size = 0; | 169 | uint64_t workspace_size = 0; |
| 169 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | 170 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); |
| 170 | - // EXPECT_EQ(aclRet, ACLNN_SUCCESS); | 171 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); |
| 171 | } | 172 | } |
| 172 | 173 | ||
| 173 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_int32_scalar) | 174 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_int32_scalar) |
| @@ -193,7 +194,7 @@ TEST_F(l2_ascend_anti_quant_test, ascend910B2_int32_scalar) | |||
| 193 | 194 | ||
| 194 | uint64_t workspace_size = 0; | 195 | uint64_t workspace_size = 0; |
| 195 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | 196 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); |
| 196 | - // EXPECT_EQ(aclRet, ACLNN_SUCCESS); | 197 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); |
| 197 | } | 198 | } |
| 198 | 199 | ||
| 199 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_input_out_dtype_dif_1) | 200 | TEST_F(l2_ascend_anti_quant_test, ascend910B2_input_out_dtype_dif_1) |
| @@ -329,7 +330,7 @@ TEST_F(l2_ascend_anti_quant_test, ascend910B2_empty_tensor) | |||
| 329 | 330 | ||
| 330 | uint64_t workspace_size = 0; | 331 | uint64_t workspace_size = 0; |
| 331 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | 332 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); |
| 332 | - // EXPECT_EQ(aclRet, ACLNN_SUCCESS); | 333 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); |
| 333 | } | 334 | } |
| 334 | 335 | ||
| 335 | TEST_F(l2_ascend_anti_quant_test, ascend910A_empty_tensor0) | 336 | TEST_F(l2_ascend_anti_quant_test, ascend910A_empty_tensor0) |
| @@ -401,7 +402,7 @@ TEST_F(l2_ascend_anti_quant_test, ascend310P_empty_tensor3) | |||
| 401 | 402 | ||
| 402 | uint64_t workspace_size = 0; | 403 | uint64_t workspace_size = 0; |
| 403 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | 404 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); |
| 404 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 405 | + // EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 405 | } | 406 | } |
| 406 | 407 | ||
| 407 | TEST_F(l2_ascend_anti_quant_test, ascend310P_check_input_bf16) | 408 | TEST_F(l2_ascend_anti_quant_test, ascend310P_check_input_bf16) |
| @@ -440,7 +441,7 @@ TEST_F(l2_ascend_anti_quant_test, ascend310P_check_output_bf16) | |||
| 440 | // EXPECT_EQ(aclRet, ACLNN_SUCCESS); | 441 | // EXPECT_EQ(aclRet, ACLNN_SUCCESS); |
| 441 | } | 442 | } |
| 442 | 443 | ||
| 443 | -TEST_F(l2_ascend_anti_quant_test, ascend910B2_empty_tensor4) | 444 | +TEST_F(l2_ascend_anti_quant_test, ascend910B2_scale_cannot_broadcast_1) |
| 444 | { | 445 | { |
| 445 | auto tensor_1_desc = TensorDesc({3, 1}, ACL_INT8, ACL_FORMAT_ND).ValueRange(-2, 2); | 446 | auto tensor_1_desc = TensorDesc({3, 1}, ACL_INT8, ACL_FORMAT_ND).ValueRange(-2, 2); |
| 446 | auto tensor_scale = TensorDesc({2}, ACL_FLOAT, ACL_FORMAT_ND); | 447 | auto tensor_scale = TensorDesc({2}, ACL_FLOAT, ACL_FORMAT_ND); |
| @@ -457,3 +458,488 @@ TEST_F(l2_ascend_anti_quant_test, ascend910B2_empty_tensor4) | |||
| 457 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | 458 | aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); |
| 458 | EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | 459 | EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); |
| 459 | } | 460 | } |
| 461 | + | ||
| 462 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_normal_1) | ||
| 463 | +{ | ||
| 464 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 465 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_HIFLOAT8, ACL_FORMAT_ND) | ||
| 466 | + .ValueRange(-2, 2) | ||
| 467 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 468 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 469 | + auto tensor_offset = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 470 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_FLOAT16, ACL_FORMAT_ND); | ||
| 471 | + int dstType = ACL_FLOAT16; | ||
| 472 | + bool sqrtMode = false; | ||
| 473 | + | ||
| 474 | + auto ut = OP_API_UT( | ||
| 475 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 476 | + OUTPUT(out_tensor_desc)); | ||
| 477 | + | ||
| 478 | + uint64_t workspace_size = 0; | ||
| 479 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 480 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 481 | +} | ||
| 482 | + | ||
| 483 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_normal_2) | ||
| 484 | +{ | ||
| 485 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 486 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_HIFLOAT8, ACL_FORMAT_ND) | ||
| 487 | + .ValueRange(-2, 2) | ||
| 488 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 489 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 490 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_BF16, ACL_FORMAT_ND); | ||
| 491 | + int dstType = ACL_BF16; | ||
| 492 | + bool sqrtMode = false; | ||
| 493 | + | ||
| 494 | + auto ut = OP_API_UT( | ||
| 495 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, (aclTensor*)nullptr, dstType, sqrtMode), | ||
| 496 | + OUTPUT(out_tensor_desc)); | ||
| 497 | + | ||
| 498 | + uint64_t workspace_size = 0; | ||
| 499 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 500 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 501 | +} | ||
| 502 | + | ||
| 503 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_normal_3) | ||
| 504 | +{ | ||
| 505 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 506 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_FLOAT8_E5M2, ACL_FORMAT_ND) | ||
| 507 | + .ValueRange(-2, 2) | ||
| 508 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 509 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 510 | + auto tensor_offset = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 511 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_FLOAT16, ACL_FORMAT_ND); | ||
| 512 | + int dstType = ACL_FLOAT16; | ||
| 513 | + bool sqrtMode = false; | ||
| 514 | + | ||
| 515 | + auto ut = OP_API_UT( | ||
| 516 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 517 | + OUTPUT(out_tensor_desc)); | ||
| 518 | + | ||
| 519 | + uint64_t workspace_size = 0; | ||
| 520 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 521 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 522 | +} | ||
| 523 | + | ||
| 524 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_normal_4) | ||
| 525 | +{ | ||
| 526 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 527 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_FLOAT8_E5M2, ACL_FORMAT_ND) | ||
| 528 | + .ValueRange(-2, 2) | ||
| 529 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 530 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 531 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_BF16, ACL_FORMAT_ND); | ||
| 532 | + int dstType = ACL_BF16; | ||
| 533 | + bool sqrtMode = false; | ||
| 534 | + | ||
| 535 | + auto ut = OP_API_UT( | ||
| 536 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, (aclTensor*)nullptr, dstType, sqrtMode), | ||
| 537 | + OUTPUT(out_tensor_desc)); | ||
| 538 | + | ||
| 539 | + uint64_t workspace_size = 0; | ||
| 540 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 541 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 542 | +} | ||
| 543 | + | ||
| 544 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_normal_5) | ||
| 545 | +{ | ||
| 546 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 547 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_FLOAT8_E4M3FN, ACL_FORMAT_ND) | ||
| 548 | + .ValueRange(-2, 2) | ||
| 549 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 550 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 551 | + auto tensor_offset = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 552 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_FLOAT16, ACL_FORMAT_ND); | ||
| 553 | + int dstType = ACL_FLOAT16; | ||
| 554 | + bool sqrtMode = false; | ||
| 555 | + | ||
| 556 | + auto ut = OP_API_UT( | ||
| 557 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 558 | + OUTPUT(out_tensor_desc)); | ||
| 559 | + | ||
| 560 | + uint64_t workspace_size = 0; | ||
| 561 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 562 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 563 | +} | ||
| 564 | + | ||
| 565 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_normal_6) | ||
| 566 | +{ | ||
| 567 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 568 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_FLOAT8_E4M3FN, ACL_FORMAT_ND) | ||
| 569 | + .ValueRange(-2, 2) | ||
| 570 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 571 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 572 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_BF16, ACL_FORMAT_ND); | ||
| 573 | + int dstType = ACL_BF16; | ||
| 574 | + bool sqrtMode = false; | ||
| 575 | + | ||
| 576 | + auto ut = OP_API_UT( | ||
| 577 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, (aclTensor*)nullptr, dstType, sqrtMode), | ||
| 578 | + OUTPUT(out_tensor_desc)); | ||
| 579 | + | ||
| 580 | + uint64_t workspace_size = 0; | ||
| 581 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 582 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 583 | +} | ||
| 584 | + | ||
| 585 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_normal_7) | ||
| 586 | +{ | ||
| 587 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 588 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_INT8, ACL_FORMAT_ND) | ||
| 589 | + .ValueRange(-2, 2) | ||
| 590 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 591 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 592 | + auto tensor_offset = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 593 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_FLOAT16, ACL_FORMAT_ND); | ||
| 594 | + int dstType = ACL_FLOAT16; | ||
| 595 | + bool sqrtMode = false; | ||
| 596 | + | ||
| 597 | + auto ut = OP_API_UT( | ||
| 598 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 599 | + OUTPUT(out_tensor_desc)); | ||
| 600 | + | ||
| 601 | + uint64_t workspace_size = 0; | ||
| 602 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 603 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 604 | +} | ||
| 605 | + | ||
| 606 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_normal_8) | ||
| 607 | +{ | ||
| 608 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 609 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_INT8, ACL_FORMAT_ND) | ||
| 610 | + .ValueRange(-2, 2) | ||
| 611 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 612 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 613 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_FLOAT16, ACL_FORMAT_ND); | ||
| 614 | + int dstType = ACL_FLOAT16; | ||
| 615 | + bool sqrtMode = false; | ||
| 616 | + | ||
| 617 | + auto ut = OP_API_UT( | ||
| 618 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, (aclTensor*)nullptr, dstType, sqrtMode), | ||
| 619 | + OUTPUT(out_tensor_desc)); | ||
| 620 | + | ||
| 621 | + uint64_t workspace_size = 0; | ||
| 622 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 623 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 624 | +} | ||
| 625 | + | ||
| 626 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_normal_9) | ||
| 627 | +{ | ||
| 628 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 629 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_INT8, ACL_FORMAT_ND) | ||
| 630 | + .ValueRange(-2, 2) | ||
| 631 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 632 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 633 | + auto tensor_offset = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 634 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_BF16, ACL_FORMAT_ND); | ||
| 635 | + int dstType = ACL_BF16; | ||
| 636 | + bool sqrtMode = false; | ||
| 637 | + | ||
| 638 | + auto ut = OP_API_UT( | ||
| 639 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 640 | + OUTPUT(out_tensor_desc)); | ||
| 641 | + | ||
| 642 | + uint64_t workspace_size = 0; | ||
| 643 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 644 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 645 | +} | ||
| 646 | + | ||
| 647 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_normal_10) | ||
| 648 | +{ | ||
| 649 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 650 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_INT8, ACL_FORMAT_ND) | ||
| 651 | + .ValueRange(-2, 2) | ||
| 652 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 653 | + auto tensor_scale = TensorDesc({1}, ACL_BF16, ACL_FORMAT_ND); | ||
| 654 | + auto tensor_offset = TensorDesc({1}, ACL_BF16, ACL_FORMAT_ND); | ||
| 655 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_BF16, ACL_FORMAT_ND); | ||
| 656 | + int dstType = ACL_BF16; | ||
| 657 | + bool sqrtMode = true; | ||
| 658 | + | ||
| 659 | + auto ut = OP_API_UT( | ||
| 660 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 661 | + OUTPUT(out_tensor_desc)); | ||
| 662 | + | ||
| 663 | + uint64_t workspace_size = 0; | ||
| 664 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 665 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 666 | +} | ||
| 667 | + | ||
| 668 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_normal_11) | ||
| 669 | +{ | ||
| 670 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 671 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_INT8, ACL_FORMAT_ND) | ||
| 672 | + .ValueRange(-2, 2) | ||
| 673 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 674 | + auto tensor_scale = TensorDesc({1}, ACL_BF16, ACL_FORMAT_ND); | ||
| 675 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_BF16, ACL_FORMAT_ND); | ||
| 676 | + int dstType = ACL_BF16; | ||
| 677 | + bool sqrtMode = true; | ||
| 678 | + | ||
| 679 | + auto ut = OP_API_UT( | ||
| 680 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, (aclTensor*)nullptr, dstType, sqrtMode), | ||
| 681 | + OUTPUT(out_tensor_desc)); | ||
| 682 | + | ||
| 683 | + uint64_t workspace_size = 0; | ||
| 684 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 685 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 686 | +} | ||
| 687 | + | ||
| 688 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_int4) | ||
| 689 | +{ | ||
| 690 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 691 | + auto tensor_1_desc = TensorDesc({3, 4}, ACL_INT4, ACL_FORMAT_ND) | ||
| 692 | + .ValueRange(-2, 2) | ||
| 693 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}); | ||
| 694 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 695 | + auto tensor_offset = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 696 | + auto out_tensor_desc = TensorDesc({3, 4}, ACL_FLOAT16, ACL_FORMAT_ND); | ||
| 697 | + int dstType = ACL_FLOAT16; | ||
| 698 | + bool sqrtMode = false; | ||
| 699 | + | ||
| 700 | + auto ut = OP_API_UT( | ||
| 701 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 702 | + OUTPUT(out_tensor_desc)); | ||
| 703 | + | ||
| 704 | + uint64_t workspace_size = 0; | ||
| 705 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 706 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 707 | +} | ||
| 708 | + | ||
| 709 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_int32) | ||
| 710 | +{ | ||
| 711 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 712 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_INT32, ACL_FORMAT_ND) | ||
| 713 | + .ValueRange(-2, 2) | ||
| 714 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 715 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 716 | + auto tensor_offset = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 717 | + auto out_tensor_desc = TensorDesc({3, 40}, ACL_FLOAT16, ACL_FORMAT_ND); | ||
| 718 | + int dstType = ACL_FLOAT16; | ||
| 719 | + bool sqrtMode = false; | ||
| 720 | + | ||
| 721 | + auto ut = OP_API_UT( | ||
| 722 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 723 | + OUTPUT(out_tensor_desc)); | ||
| 724 | + | ||
| 725 | + uint64_t workspace_size = 0; | ||
| 726 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 727 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 728 | +} | ||
| 729 | + | ||
| 730 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_scale_dim_not_1_01) | ||
| 731 | +{ | ||
| 732 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 733 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_HIFLOAT8, ACL_FORMAT_ND) | ||
| 734 | + .ValueRange(-2, 2) | ||
| 735 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 736 | + auto tensor_scale = TensorDesc({1, 5}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 737 | + auto tensor_offset = TensorDesc({1, 5}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 738 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_FLOAT16, ACL_FORMAT_ND); | ||
| 739 | + int dstType = ACL_FLOAT16; | ||
| 740 | + bool sqrtMode = false; | ||
| 741 | + | ||
| 742 | + auto ut = OP_API_UT( | ||
| 743 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 744 | + OUTPUT(out_tensor_desc)); | ||
| 745 | + | ||
| 746 | + uint64_t workspace_size = 0; | ||
| 747 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 748 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 749 | +} | ||
| 750 | + | ||
| 751 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_per_head_1) | ||
| 752 | +{ | ||
| 753 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 754 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_HIFLOAT8, ACL_FORMAT_ND) | ||
| 755 | + .ValueRange(-2, 2) | ||
| 756 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 757 | + auto tensor_scale = TensorDesc({3, 1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 758 | + auto tensor_offset = TensorDesc({3, 1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 759 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_BF16, ACL_FORMAT_ND); | ||
| 760 | + int dstType = ACL_BF16; | ||
| 761 | + bool sqrtMode = false; | ||
| 762 | + | ||
| 763 | + auto ut = OP_API_UT( | ||
| 764 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 765 | + OUTPUT(out_tensor_desc)); | ||
| 766 | + | ||
| 767 | + uint64_t workspace_size = 0; | ||
| 768 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 769 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 770 | +} | ||
| 771 | + | ||
| 772 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_per_head_2) | ||
| 773 | +{ | ||
| 774 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 775 | + auto tensor_1_desc = TensorDesc({3, 4}, ACL_INT4, ACL_FORMAT_ND) | ||
| 776 | + .ValueRange(-2, 2); | ||
| 777 | + auto tensor_scale = TensorDesc({3}, ACL_BF16, ACL_FORMAT_ND); | ||
| 778 | + auto tensor_offset = TensorDesc({3}, ACL_BF16, ACL_FORMAT_ND); | ||
| 779 | + auto out_tensor_desc = TensorDesc({3, 4}, ACL_BF16, ACL_FORMAT_ND); | ||
| 780 | + int dstType = ACL_BF16; | ||
| 781 | + bool sqrtMode = true; | ||
| 782 | + | ||
| 783 | + auto ut = OP_API_UT( | ||
| 784 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 785 | + OUTPUT(out_tensor_desc)); | ||
| 786 | + | ||
| 787 | + uint64_t workspace_size = 0; | ||
| 788 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 789 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 790 | +} | ||
| 791 | + | ||
| 792 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_int32_scalar) | ||
| 793 | +{ | ||
| 794 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 795 | + auto tensor_1_desc = TensorDesc({}, ACL_INT32, ACL_FORMAT_ND) | ||
| 796 | + .ValueRange(-2, 2) | ||
| 797 | + .Value(vector<float>{ | ||
| 798 | + 1, | ||
| 799 | + }); | ||
| 800 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 801 | + auto tensor_offset = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 802 | + auto out_tensor_desc = TensorDesc( | ||
| 803 | + { | ||
| 804 | + 8, | ||
| 805 | + }, | ||
| 806 | + ACL_FLOAT16, ACL_FORMAT_ND); | ||
| 807 | + int dstType = ACL_FLOAT16; | ||
| 808 | + bool sqrtMode = false; | ||
| 809 | + | ||
| 810 | + auto ut = OP_API_UT( | ||
| 811 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 812 | + OUTPUT(out_tensor_desc)); | ||
| 813 | + | ||
| 814 | + uint64_t workspace_size = 0; | ||
| 815 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 816 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 817 | +} | ||
| 818 | + | ||
| 819 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_hifloat8_scalar) | ||
| 820 | +{ | ||
| 821 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 822 | + auto tensor_1_desc = TensorDesc({}, ACL_HIFLOAT8, ACL_FORMAT_ND) | ||
| 823 | + .ValueRange(-2, 2) | ||
| 824 | + .Value(vector<float>{ | ||
| 825 | + 1, | ||
| 826 | + }); | ||
| 827 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 828 | + auto tensor_offset = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 829 | + auto out_tensor_desc = TensorDesc( | ||
| 830 | + { | ||
| 831 | + 8, | ||
| 832 | + }, | ||
| 833 | + ACL_FLOAT16, ACL_FORMAT_ND); | ||
| 834 | + int dstType = ACL_FLOAT16; | ||
| 835 | + bool sqrtMode = false; | ||
| 836 | + | ||
| 837 | + auto ut = OP_API_UT( | ||
| 838 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 839 | + OUTPUT(out_tensor_desc)); | ||
| 840 | + | ||
| 841 | + uint64_t workspace_size = 0; | ||
| 842 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 843 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | ||
| 844 | +} | ||
| 845 | + | ||
| 846 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_input_out_dtype_dif_1) | ||
| 847 | +{ | ||
| 848 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 849 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_INT8, ACL_FORMAT_ND) | ||
| 850 | + .ValueRange(-2, 2) | ||
| 851 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 852 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 853 | + auto tensor_offset = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 854 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_BF16, ACL_FORMAT_ND); | ||
| 855 | + int dstType = ACL_FLOAT16; | ||
| 856 | + bool sqrtMode = false; | ||
| 857 | + | ||
| 858 | + auto ut = OP_API_UT( | ||
| 859 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 860 | + OUTPUT(out_tensor_desc)); | ||
| 861 | + | ||
| 862 | + uint64_t workspace_size = 0; | ||
| 863 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 864 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | ||
| 865 | +} | ||
| 866 | + | ||
| 867 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_input_out_dtype_dif_2) | ||
| 868 | +{ | ||
| 869 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 870 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_INT8, ACL_FORMAT_ND) | ||
| 871 | + .ValueRange(-2, 2) | ||
| 872 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 873 | + auto tensor_scale = TensorDesc({1}, ACL_BF16, ACL_FORMAT_ND); | ||
| 874 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_BF16, ACL_FORMAT_ND); | ||
| 875 | + int dstType = ACL_FLOAT16; | ||
| 876 | + bool sqrtMode = false; | ||
| 877 | + | ||
| 878 | + auto ut = OP_API_UT( | ||
| 879 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, (aclTensor*)nullptr, dstType, sqrtMode), | ||
| 880 | + OUTPUT(out_tensor_desc)); | ||
| 881 | + | ||
| 882 | + uint64_t workspace_size = 0; | ||
| 883 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 884 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | ||
| 885 | +} | ||
| 886 | + | ||
| 887 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_offset_dim_not_1) | ||
| 888 | +{ | ||
| 889 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 890 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_INT8, ACL_FORMAT_ND) | ||
| 891 | + .ValueRange(-2, 2) | ||
| 892 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 893 | + auto tensor_scale = TensorDesc({1, 2}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 894 | + auto tensor_offset = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 895 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_FLOAT16, ACL_FORMAT_ND); | ||
| 896 | + int dstType = ACL_FLOAT16; | ||
| 897 | + bool sqrtMode = false; | ||
| 898 | + | ||
| 899 | + auto ut = OP_API_UT( | ||
| 900 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 901 | + OUTPUT(out_tensor_desc)); | ||
| 902 | + | ||
| 903 | + uint64_t workspace_size = 0; | ||
| 904 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 905 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | ||
| 906 | +} | ||
| 907 | + | ||
| 908 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_scale_dim_not_1_Nonoffset) | ||
| 909 | +{ | ||
| 910 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 911 | + auto tensor_1_desc = TensorDesc({3, 5}, ACL_INT8, ACL_FORMAT_ND) | ||
| 912 | + .ValueRange(-2, 2) | ||
| 913 | + .Value(vector<float>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); | ||
| 914 | + auto tensor_scale = TensorDesc({1, 2}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 915 | + auto out_tensor_desc = TensorDesc({3, 5}, ACL_BF16, ACL_FORMAT_ND); | ||
| 916 | + int dstType = ACL_FLOAT16; | ||
| 917 | + bool sqrtMode = false; | ||
| 918 | + | ||
| 919 | + auto ut = OP_API_UT( | ||
| 920 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, (aclTensor*)nullptr, dstType, sqrtMode), | ||
| 921 | + OUTPUT(out_tensor_desc)); | ||
| 922 | + | ||
| 923 | + uint64_t workspace_size = 0; | ||
| 924 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 925 | + EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | ||
| 926 | +} | ||
| 927 | + | ||
| 928 | +TEST_F(l2_ascend_anti_quant_test, ascend950PR_empty_tensor) | ||
| 929 | +{ | ||
| 930 | + op::SocVersionManager versionManager(op::SocVersion::ASCEND950); | ||
| 931 | + auto tensor_1_desc = TensorDesc({3, 0}, ACL_INT8, ACL_FORMAT_ND).ValueRange(-2, 2); | ||
| 932 | + auto tensor_scale = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 933 | + auto tensor_offset = TensorDesc({1}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 934 | + auto out_tensor_desc = TensorDesc({3, 0}, ACL_FLOAT16, ACL_FORMAT_ND); | ||
| 935 | + int dstType = ACL_FLOAT16; | ||
| 936 | + bool sqrtMode = false; | ||
| 937 | + | ||
| 938 | + auto ut = OP_API_UT( | ||
| 939 | + aclnnAscendAntiQuant, INPUT(tensor_1_desc, tensor_scale, tensor_offset, dstType, sqrtMode), | ||
| 940 | + OUTPUT(out_tensor_desc)); | ||
| 941 | + | ||
| 942 | + uint64_t workspace_size = 0; | ||
| 943 | + aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 944 | + EXPECT_EQ(aclRet, ACLNN_SUCCESS); | ||
| 945 | +} | ||
| @@ -0,0 +1,1166 @@ | |||
| 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 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | +using namespace std; | ||
| 24 | +using namespace ge; | ||
| 25 | +using namespace ut_util; | ||
| 26 | + | ||
| 27 | +class AscendAntiQuantV2Tiling : public testing::Test { | ||
| 28 | +protected: | ||
| 29 | + static void SetUpTestCase() | ||
| 30 | + { | ||
| 31 | + std::cout << "AscendAntiQuantV2Tiling SetUp" << std::endl; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + static void TearDownTestCase() | ||
| 35 | + { | ||
| 36 | + std::cout << "AscendAntiQuantV2Tiling TearDown" << std::endl; | ||
| 37 | + } | ||
| 38 | +}; | ||
| 39 | + | ||
| 40 | +struct AscendAntiQuantV2CompileInfo { | ||
| 41 | + int32_t vectorCoreNum = 0; | ||
| 42 | + uint64_t ubSize = 0; | ||
| 43 | + bool isAscend910B = false; | ||
| 44 | +}; | ||
| 45 | + | ||
| 46 | +static string TilingData2Str(const gert::TilingData* tiling_data) | ||
| 47 | +{ | ||
| 48 | + auto data = tiling_data->GetData(); | ||
| 49 | + string result; | ||
| 50 | + for (size_t i = 0; i < tiling_data->GetDataSize(); i += sizeof(int64_t)) { | ||
| 51 | + result += std::to_string((reinterpret_cast<const int64_t*>(tiling_data->GetData())[i / sizeof(int64_t)])); | ||
| 52 | + result += " "; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + return result; | ||
| 56 | +} | ||
| 57 | + | ||
| 58 | +static void InitPlatForm( | ||
| 59 | + fe::PlatFormInfos& platform_info, map<string, string>& soc_infos, map<string, string>& aicore_spec, | ||
| 60 | + map<string, string>& intrinsics) | ||
| 61 | +{ | ||
| 62 | + string compile_info_string = R"({ | ||
| 63 | + "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1", | ||
| 64 | + "Intrinsic_fix_pipe_l0c2out": false, | ||
| 65 | + "Intrinsic_data_move_l12ub": true, | ||
| 66 | + "Intrinsic_data_move_l0c2ub": true, | ||
| 67 | + "Intrinsic_data_move_out2l1_nd2nz": false, | ||
| 68 | + "UB_SIZE": 196608, "L2_SIZE": 33554432, "L1_SIZE": 524288, | ||
| 69 | + "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072, | ||
| 70 | + "CORE_NUM": 48} | ||
| 71 | + })"; | ||
| 72 | + GetPlatFormInfos(compile_info_string.c_str(), soc_infos, aicore_spec, intrinsics); | ||
| 73 | + | ||
| 74 | + platform_info.Init(); | ||
| 75 | +} | ||
| 76 | + | ||
| 77 | +TEST_F(AscendAntiQuantV2Tiling, ascend_anti_quant_v2_tiling_per_channel_950_1) | ||
| 78 | +{ | ||
| 79 | + // test int8, block cut last axis | ||
| 80 | + fe::PlatFormInfos platform_info; | ||
| 81 | + map<string, string> soc_infos; | ||
| 82 | + map<string, string> aicore_spec; | ||
| 83 | + map<string, string> intrinsics; | ||
| 84 | + InitPlatForm(platform_info, soc_infos, aicore_spec, intrinsics); | ||
| 85 | + map<string, string> socversions = {{"Short_SoC_version", "Ascend950"}, {"NpuArch", "3510"}}; | ||
| 86 | + string compile_info_string = R"({ | ||
| 87 | + "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1", | ||
| 88 | + "Intrinsic_fix_pipe_l0c2out": false, | ||
| 89 | + "Intrinsic_data_move_l12ub": true, | ||
| 90 | + "Intrinsic_data_move_l0c2ub": true, | ||
| 91 | + "Intrinsic_data_move_out2l1_nd2nz": false, | ||
| 92 | + "UB_SIZE": 196608, "L2_SIZE": 33554432, "L1_SIZE": 524288, | ||
| 93 | + "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072, | ||
| 94 | + "CORE_NUM": 48} | ||
| 95 | + })"; | ||
| 96 | + | ||
| 97 | + gert::StorageShape x_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 98 | + gert::StorageShape scale_shape = {{10240}, {10240}}; | ||
| 99 | + gert::StorageShape offset_shape = {{10240}, {10240}}; | ||
| 100 | + gert::StorageShape out_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 101 | + | ||
| 102 | + AscendAntiQuantV2CompileInfo compile_info; | ||
| 103 | + std::string op_type("AscendAntiQuantV2"); | ||
| 104 | + ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str()), nullptr); | ||
| 105 | + auto tiling_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling; | ||
| 106 | + auto tiling_parse_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling_parse; | ||
| 107 | + | ||
| 108 | + // tilingParseFunc simulate | ||
| 109 | + auto kernel_holder = | ||
| 110 | + gert::KernelRunContextFaker() | ||
| 111 | + .KernelIONum(2, 1) | ||
| 112 | + .Inputs({const_cast<char*>(compile_info_string.c_str()), reinterpret_cast<void*>(&platform_info)}) | ||
| 113 | + .Outputs({&compile_info}) | ||
| 114 | + .Build(); | ||
| 115 | + | ||
| 116 | + ASSERT_TRUE(kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->Init()); | ||
| 117 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 118 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 119 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 120 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes( | ||
| 121 | + "AICoreintrinsicDtypeMap", intrinsics); | ||
| 122 | + | ||
| 123 | + ASSERT_EQ(tiling_parse_func(kernel_holder.GetContext<gert::KernelContext>()), ge::GRAPH_SUCCESS); | ||
| 124 | + | ||
| 125 | + // tilingFunc simulate | ||
| 126 | + auto param = gert::TilingData::CreateCap(4096); | ||
| 127 | + auto workspace_size_holer = gert::ContinuousVector::Create<size_t>(16 * 1024 * 1024); | ||
| 128 | + auto ws_size = reinterpret_cast<gert::ContinuousVector*>(workspace_size_holer.get()); | ||
| 129 | + ASSERT_NE(param, nullptr); | ||
| 130 | + auto holder = gert::TilingContextFaker() | ||
| 131 | + .NodeIoNum(3, 1) | ||
| 132 | + .IrInstanceNum({1, 1, 1}) | ||
| 133 | + .InputShapes({&x_shape, &scale_shape, &offset_shape}) | ||
| 134 | + .OutputShapes({&out_shape}) | ||
| 135 | + .CompileInfo(&compile_info) | ||
| 136 | + .PlatformInfo(reinterpret_cast<char*>(&platform_info)) | ||
| 137 | + .NodeInputTd(0, ge::DT_INT8, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 138 | + .NodeInputTd(1, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 139 | + .NodeInputTd(2, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 140 | + .NodeOutputTd(0, ge::DT_BF16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 141 | + .NodeAttrs({ | ||
| 142 | + {"dst_type", Ops::NN::AnyValue::CreateFrom<int64_t>(27)}, | ||
| 143 | + {"sqrt_mode", Ops::NN::AnyValue::CreateFrom<bool>(false)} | ||
| 144 | + }) | ||
| 145 | + .TilingData(param.get()) | ||
| 146 | + .Workspace(ws_size) | ||
| 147 | + .Build(); | ||
| 148 | + | ||
| 149 | + gert::TilingContext* tiling_context = holder.GetContext<gert::TilingContext>(); | ||
| 150 | + ASSERT_NE(tiling_context->GetPlatformInfo(), nullptr); | ||
| 151 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 152 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 153 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 154 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics); | ||
| 155 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", socversions); | ||
| 156 | + | ||
| 157 | + EXPECT_EQ(tiling_func(tiling_context), ge::GRAPH_SUCCESS); | ||
| 158 | + | ||
| 159 | +} | ||
| 160 | + | ||
| 161 | +TEST_F(AscendAntiQuantV2Tiling, ascend_anti_quant_v2_tiling_per_tensor_950_2) | ||
| 162 | +{ | ||
| 163 | + // test hifloat8, block cut last axis | ||
| 164 | + fe::PlatFormInfos platform_info; | ||
| 165 | + map<string, string> soc_infos; | ||
| 166 | + map<string, string> aicore_spec; | ||
| 167 | + map<string, string> intrinsics; | ||
| 168 | + InitPlatForm(platform_info, soc_infos, aicore_spec, intrinsics); | ||
| 169 | + map<string, string> socversions = {{"Short_SoC_version", "Ascend950"}, {"NpuArch", "3510"}}; | ||
| 170 | + map<string, string> npuarchs = {{"NpuArch", "3510"}}; | ||
| 171 | + string compile_info_string = R"({ | ||
| 172 | + "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1", | ||
| 173 | + "Intrinsic_fix_pipe_l0c2out": false, | ||
| 174 | + "Intrinsic_data_move_l12ub": true, | ||
| 175 | + "Intrinsic_data_move_l0c2ub": true, | ||
| 176 | + "Intrinsic_data_move_out2l1_nd2nz": false, | ||
| 177 | + "UB_SIZE": 196608, "L2_SIZE": 33554432, "L1_SIZE": 524288, | ||
| 178 | + "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072, | ||
| 179 | + "CORE_NUM": 48} | ||
| 180 | + })"; | ||
| 181 | + | ||
| 182 | + gert::StorageShape x_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 183 | + gert::StorageShape scale_shape = {{1}, {1}}; | ||
| 184 | + gert::StorageShape offset_shape = {{1}, {1}}; | ||
| 185 | + gert::StorageShape out_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 186 | + | ||
| 187 | + AscendAntiQuantV2CompileInfo compile_info; | ||
| 188 | + std::string op_type("AscendAntiQuantV2"); | ||
| 189 | + ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str()), nullptr); | ||
| 190 | + auto tiling_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling; | ||
| 191 | + auto tiling_parse_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling_parse; | ||
| 192 | + | ||
| 193 | + // tilingParseFunc simulate | ||
| 194 | + auto kernel_holder = | ||
| 195 | + gert::KernelRunContextFaker() | ||
| 196 | + .KernelIONum(2, 1) | ||
| 197 | + .Inputs({const_cast<char*>(compile_info_string.c_str()), reinterpret_cast<void*>(&platform_info)}) | ||
| 198 | + .Outputs({&compile_info}) | ||
| 199 | + .Build(); | ||
| 200 | + | ||
| 201 | + ASSERT_TRUE(kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->Init()); | ||
| 202 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 203 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 204 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 205 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes( | ||
| 206 | + "AICoreintrinsicDtypeMap", intrinsics); | ||
| 207 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("version", npuarchs); | ||
| 208 | + | ||
| 209 | + ASSERT_EQ(tiling_parse_func(kernel_holder.GetContext<gert::KernelContext>()), ge::GRAPH_SUCCESS); | ||
| 210 | + | ||
| 211 | + // tilingFunc simulate | ||
| 212 | + auto param = gert::TilingData::CreateCap(4096); | ||
| 213 | + auto workspace_size_holer = gert::ContinuousVector::Create<size_t>(16 * 1024 * 1024); | ||
| 214 | + auto ws_size = reinterpret_cast<gert::ContinuousVector*>(workspace_size_holer.get()); | ||
| 215 | + ASSERT_NE(param, nullptr); | ||
| 216 | + auto holder = gert::TilingContextFaker() | ||
| 217 | + .NodeIoNum(3, 1) | ||
| 218 | + .IrInstanceNum({1, 1, 1}) | ||
| 219 | + .InputShapes({&x_shape, &scale_shape, &offset_shape}) | ||
| 220 | + .OutputShapes({&out_shape}) | ||
| 221 | + .CompileInfo(&compile_info) | ||
| 222 | + .PlatformInfo(reinterpret_cast<char*>(&platform_info)) | ||
| 223 | + .NodeInputTd(0, ge::DT_HIFLOAT8, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 224 | + .NodeInputTd(1, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 225 | + .NodeInputTd(2, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 226 | + .NodeOutputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 227 | + .NodeAttrs({ | ||
| 228 | + {"dst_type", Ops::NN::AnyValue::CreateFrom<int64_t>(1)}, | ||
| 229 | + {"sqrt_mode", Ops::NN::AnyValue::CreateFrom<bool>(false)} | ||
| 230 | + }) | ||
| 231 | + .TilingData(param.get()) | ||
| 232 | + .Workspace(ws_size) | ||
| 233 | + .Build(); | ||
| 234 | + | ||
| 235 | + gert::TilingContext* tiling_context = holder.GetContext<gert::TilingContext>(); | ||
| 236 | + ASSERT_NE(tiling_context->GetPlatformInfo(), nullptr); | ||
| 237 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 238 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 239 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 240 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics); | ||
| 241 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("version", npuarchs); | ||
| 242 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", socversions); | ||
| 243 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", npuarchs); | ||
| 244 | + | ||
| 245 | + EXPECT_EQ(tiling_func(tiling_context), ge::GRAPH_SUCCESS); | ||
| 246 | + | ||
| 247 | +} | ||
| 248 | + | ||
| 249 | +TEST_F(AscendAntiQuantV2Tiling, ascend_anti_quant_v2_tiling_per_channel_no_offset_950_3) | ||
| 250 | +{ | ||
| 251 | + // test float8_e5m2, block cut last axis | ||
| 252 | + fe::PlatFormInfos platform_info; | ||
| 253 | + map<string, string> soc_infos; | ||
| 254 | + map<string, string> aicore_spec; | ||
| 255 | + map<string, string> intrinsics; | ||
| 256 | + InitPlatForm(platform_info, soc_infos, aicore_spec, intrinsics); | ||
| 257 | + map<string, string> socversions = {{"Short_SoC_version", "Ascend950"}, {"NpuArch", "3510"}}; | ||
| 258 | + string compile_info_string = R"({ | ||
| 259 | + "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1", | ||
| 260 | + "Intrinsic_fix_pipe_l0c2out": false, | ||
| 261 | + "Intrinsic_data_move_l12ub": true, | ||
| 262 | + "Intrinsic_data_move_l0c2ub": true, | ||
| 263 | + "Intrinsic_data_move_out2l1_nd2nz": false, | ||
| 264 | + "UB_SIZE": 196608, "L2_SIZE": 33554432, "L1_SIZE": 524288, | ||
| 265 | + "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072, | ||
| 266 | + "CORE_NUM": 48} | ||
| 267 | + })"; | ||
| 268 | + | ||
| 269 | + gert::StorageShape x_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 270 | + gert::StorageShape scale_shape = {{10240}, {10240}}; | ||
| 271 | + gert::StorageShape out_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 272 | + | ||
| 273 | + AscendAntiQuantV2CompileInfo compile_info; | ||
| 274 | + std::string op_type("AscendAntiQuantV2"); | ||
| 275 | + ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str()), nullptr); | ||
| 276 | + auto tiling_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling; | ||
| 277 | + auto tiling_parse_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling_parse; | ||
| 278 | + | ||
| 279 | + // tilingParseFunc simulate | ||
| 280 | + auto kernel_holder = | ||
| 281 | + gert::KernelRunContextFaker() | ||
| 282 | + .KernelIONum(2, 1) | ||
| 283 | + .Inputs({const_cast<char*>(compile_info_string.c_str()), reinterpret_cast<void*>(&platform_info)}) | ||
| 284 | + .Outputs({&compile_info}) | ||
| 285 | + .Build(); | ||
| 286 | + | ||
| 287 | + ASSERT_TRUE(kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->Init()); | ||
| 288 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 289 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 290 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 291 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes( | ||
| 292 | + "AICoreintrinsicDtypeMap", intrinsics); | ||
| 293 | + | ||
| 294 | + ASSERT_EQ(tiling_parse_func(kernel_holder.GetContext<gert::KernelContext>()), ge::GRAPH_SUCCESS); | ||
| 295 | + | ||
| 296 | + // tilingFunc simulate | ||
| 297 | + auto param = gert::TilingData::CreateCap(4096); | ||
| 298 | + auto workspace_size_holer = gert::ContinuousVector::Create<size_t>(16 * 1024 * 1024); | ||
| 299 | + auto ws_size = reinterpret_cast<gert::ContinuousVector*>(workspace_size_holer.get()); | ||
| 300 | + ASSERT_NE(param, nullptr); | ||
| 301 | + auto holder = gert::TilingContextFaker() | ||
| 302 | + .NodeIoNum(3, 1) | ||
| 303 | + .IrInstanceNum({1, 1, 0}) | ||
| 304 | + .InputShapes({&x_shape, &scale_shape}) | ||
| 305 | + .OutputShapes({&out_shape}) | ||
| 306 | + .CompileInfo(&compile_info) | ||
| 307 | + .PlatformInfo(reinterpret_cast<char*>(&platform_info)) | ||
| 308 | + .NodeInputTd(0, ge::DT_FLOAT8_E5M2, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 309 | + .NodeInputTd(1, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 310 | + .NodeOutputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 311 | + .NodeAttrs({ | ||
| 312 | + {"dst_type", Ops::NN::AnyValue::CreateFrom<int64_t>(1)}, | ||
| 313 | + {"sqrt_mode", Ops::NN::AnyValue::CreateFrom<bool>(false)} | ||
| 314 | + }) | ||
| 315 | + .TilingData(param.get()) | ||
| 316 | + .Workspace(ws_size) | ||
| 317 | + .Build(); | ||
| 318 | + | ||
| 319 | + gert::TilingContext* tiling_context = holder.GetContext<gert::TilingContext>(); | ||
| 320 | + ASSERT_NE(tiling_context->GetPlatformInfo(), nullptr); | ||
| 321 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 322 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 323 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 324 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics); | ||
| 325 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", socversions); | ||
| 326 | + | ||
| 327 | + EXPECT_EQ(tiling_func(tiling_context), ge::GRAPH_SUCCESS); | ||
| 328 | +} | ||
| 329 | + | ||
| 330 | +TEST_F(AscendAntiQuantV2Tiling, ascend_anti_quant_v2_tiling_per_tensor_no_offset_950_4) | ||
| 331 | +{ | ||
| 332 | + // test float8_e4m3, block cut last axis | ||
| 333 | + fe::PlatFormInfos platform_info; | ||
| 334 | + map<string, string> soc_infos; | ||
| 335 | + map<string, string> aicore_spec; | ||
| 336 | + map<string, string> intrinsics; | ||
| 337 | + InitPlatForm(platform_info, soc_infos, aicore_spec, intrinsics); | ||
| 338 | + map<string, string> socversions = {{"Short_SoC_version", "Ascend950"}, {"NpuArch", "3510"}}; | ||
| 339 | + string compile_info_string = R"({ | ||
| 340 | + "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1", | ||
| 341 | + "Intrinsic_fix_pipe_l0c2out": false, | ||
| 342 | + "Intrinsic_data_move_l12ub": true, | ||
| 343 | + "Intrinsic_data_move_l0c2ub": true, | ||
| 344 | + "Intrinsic_data_move_out2l1_nd2nz": false, | ||
| 345 | + "UB_SIZE": 196608, "L2_SIZE": 33554432, "L1_SIZE": 524288, | ||
| 346 | + "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072, | ||
| 347 | + "CORE_NUM": 48} | ||
| 348 | + })"; | ||
| 349 | + | ||
| 350 | + gert::StorageShape x_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 351 | + gert::StorageShape scale_shape = {{1}, {1}}; | ||
| 352 | + gert::StorageShape out_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 353 | + | ||
| 354 | + AscendAntiQuantV2CompileInfo compile_info; | ||
| 355 | + std::string op_type("AscendAntiQuantV2"); | ||
| 356 | + ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str()), nullptr); | ||
| 357 | + auto tiling_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling; | ||
| 358 | + auto tiling_parse_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling_parse; | ||
| 359 | + | ||
| 360 | + // tilingParseFunc simulate | ||
| 361 | + auto kernel_holder = | ||
| 362 | + gert::KernelRunContextFaker() | ||
| 363 | + .KernelIONum(2, 1) | ||
| 364 | + .Inputs({const_cast<char*>(compile_info_string.c_str()), reinterpret_cast<void*>(&platform_info)}) | ||
| 365 | + .Outputs({&compile_info}) | ||
| 366 | + .Build(); | ||
| 367 | + | ||
| 368 | + ASSERT_TRUE(kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->Init()); | ||
| 369 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 370 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 371 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 372 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes( | ||
| 373 | + "AICoreintrinsicDtypeMap", intrinsics); | ||
| 374 | + | ||
| 375 | + ASSERT_EQ(tiling_parse_func(kernel_holder.GetContext<gert::KernelContext>()), ge::GRAPH_SUCCESS); | ||
| 376 | + | ||
| 377 | + // tilingFunc simulate | ||
| 378 | + auto param = gert::TilingData::CreateCap(4096); | ||
| 379 | + auto workspace_size_holer = gert::ContinuousVector::Create<size_t>(16 * 1024 * 1024); | ||
| 380 | + auto ws_size = reinterpret_cast<gert::ContinuousVector*>(workspace_size_holer.get()); | ||
| 381 | + ASSERT_NE(param, nullptr); | ||
| 382 | + auto holder = gert::TilingContextFaker() | ||
| 383 | + .NodeIoNum(3, 1) | ||
| 384 | + .IrInstanceNum({1, 1, 0}) | ||
| 385 | + .InputShapes({&x_shape, &scale_shape}) | ||
| 386 | + .OutputShapes({&out_shape}) | ||
| 387 | + .CompileInfo(&compile_info) | ||
| 388 | + .PlatformInfo(reinterpret_cast<char*>(&platform_info)) | ||
| 389 | + .NodeInputTd(0, ge::DT_FLOAT8_E4M3FN, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 390 | + .NodeInputTd(1, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 391 | + .NodeOutputTd(0, ge::DT_BF16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 392 | + .NodeAttrs({ | ||
| 393 | + {"dst_type", Ops::NN::AnyValue::CreateFrom<int64_t>(27)}, | ||
| 394 | + {"sqrt_mode", Ops::NN::AnyValue::CreateFrom<bool>(false)} | ||
| 395 | + }) | ||
| 396 | + .TilingData(param.get()) | ||
| 397 | + .Workspace(ws_size) | ||
| 398 | + .Build(); | ||
| 399 | + | ||
| 400 | + gert::TilingContext* tiling_context = holder.GetContext<gert::TilingContext>(); | ||
| 401 | + ASSERT_NE(tiling_context->GetPlatformInfo(), nullptr); | ||
| 402 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 403 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 404 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 405 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics); | ||
| 406 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", socversions); | ||
| 407 | + | ||
| 408 | + EXPECT_EQ(tiling_func(tiling_context), ge::GRAPH_SUCCESS); | ||
| 409 | +} | ||
| 410 | + | ||
| 411 | +TEST_F(AscendAntiQuantV2Tiling, ascend_anti_quant_v2_tiling_int4_950_5) | ||
| 412 | +{ | ||
| 413 | + // test int4, block cut last axis | ||
| 414 | + fe::PlatFormInfos platform_info; | ||
| 415 | + map<string, string> soc_infos; | ||
| 416 | + map<string, string> aicore_spec; | ||
| 417 | + map<string, string> intrinsics; | ||
| 418 | + InitPlatForm(platform_info, soc_infos, aicore_spec, intrinsics); | ||
| 419 | + map<string, string> socversions = {{"Short_SoC_version", "Ascend950"}, {"NpuArch", "3510"}}; | ||
| 420 | + string compile_info_string = R"({ | ||
| 421 | + "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1", | ||
| 422 | + "Intrinsic_fix_pipe_l0c2out": false, | ||
| 423 | + "Intrinsic_data_move_l12ub": true, | ||
| 424 | + "Intrinsic_data_move_l0c2ub": true, | ||
| 425 | + "Intrinsic_data_move_out2l1_nd2nz": false, | ||
| 426 | + "UB_SIZE": 196608, "L2_SIZE": 33554432, "L1_SIZE": 524288, | ||
| 427 | + "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072, | ||
| 428 | + "CORE_NUM": 48} | ||
| 429 | + })"; | ||
| 430 | + | ||
| 431 | + gert::StorageShape x_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 432 | + gert::StorageShape scale_shape = {{10240}, {10240}}; | ||
| 433 | + gert::StorageShape offset_shape = {{10240}, {10240}}; | ||
| 434 | + gert::StorageShape out_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 435 | + | ||
| 436 | + AscendAntiQuantV2CompileInfo compile_info; | ||
| 437 | + std::string op_type("AscendAntiQuantV2"); | ||
| 438 | + ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str()), nullptr); | ||
| 439 | + auto tiling_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling; | ||
| 440 | + auto tiling_parse_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling_parse; | ||
| 441 | + | ||
| 442 | + // tilingParseFunc simulate | ||
| 443 | + auto kernel_holder = | ||
| 444 | + gert::KernelRunContextFaker() | ||
| 445 | + .KernelIONum(2, 1) | ||
| 446 | + .Inputs({const_cast<char*>(compile_info_string.c_str()), reinterpret_cast<void*>(&platform_info)}) | ||
| 447 | + .Outputs({&compile_info}) | ||
| 448 | + .Build(); | ||
| 449 | + | ||
| 450 | + ASSERT_TRUE(kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->Init()); | ||
| 451 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 452 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 453 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 454 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes( | ||
| 455 | + "AICoreintrinsicDtypeMap", intrinsics); | ||
| 456 | + | ||
| 457 | + ASSERT_EQ(tiling_parse_func(kernel_holder.GetContext<gert::KernelContext>()), ge::GRAPH_SUCCESS); | ||
| 458 | + | ||
| 459 | + // tilingFunc simulate | ||
| 460 | + auto param = gert::TilingData::CreateCap(4096); | ||
| 461 | + auto workspace_size_holer = gert::ContinuousVector::Create<size_t>(16 * 1024 * 1024); | ||
| 462 | + auto ws_size = reinterpret_cast<gert::ContinuousVector*>(workspace_size_holer.get()); | ||
| 463 | + ASSERT_NE(param, nullptr); | ||
| 464 | + auto holder = gert::TilingContextFaker() | ||
| 465 | + .NodeIoNum(3, 1) | ||
| 466 | + .IrInstanceNum({1, 1, 1}) | ||
| 467 | + .InputShapes({&x_shape, &scale_shape, &offset_shape}) | ||
| 468 | + .OutputShapes({&out_shape}) | ||
| 469 | + .CompileInfo(&compile_info) | ||
| 470 | + .PlatformInfo(reinterpret_cast<char*>(&platform_info)) | ||
| 471 | + .NodeInputTd(0, ge::DT_INT4, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 472 | + .NodeInputTd(1, ge::DT_BF16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 473 | + .NodeInputTd(2, ge::DT_BF16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 474 | + .NodeOutputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 475 | + .NodeAttrs({ | ||
| 476 | + {"dst_type", Ops::NN::AnyValue::CreateFrom<int64_t>(1)}, | ||
| 477 | + {"sqrt_mode", Ops::NN::AnyValue::CreateFrom<bool>(false)} | ||
| 478 | + }) | ||
| 479 | + .TilingData(param.get()) | ||
| 480 | + .Workspace(ws_size) | ||
| 481 | + .Build(); | ||
| 482 | + | ||
| 483 | + gert::TilingContext* tiling_context = holder.GetContext<gert::TilingContext>(); | ||
| 484 | + ASSERT_NE(tiling_context->GetPlatformInfo(), nullptr); | ||
| 485 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 486 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 487 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 488 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics); | ||
| 489 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", socversions); | ||
| 490 | + | ||
| 491 | + EXPECT_EQ(tiling_func(tiling_context), ge::GRAPH_SUCCESS); | ||
| 492 | +} | ||
| 493 | + | ||
| 494 | +TEST_F(AscendAntiQuantV2Tiling, ascend_anti_quant_v2_tiling_per_head_950_6) | ||
| 495 | +{ | ||
| 496 | + // test int4, block cut -2 axis | ||
| 497 | + fe::PlatFormInfos platform_info; | ||
| 498 | + map<string, string> soc_infos; | ||
| 499 | + map<string, string> aicore_spec; | ||
| 500 | + map<string, string> intrinsics; | ||
| 501 | + InitPlatForm(platform_info, soc_infos, aicore_spec, intrinsics); | ||
| 502 | + map<string, string> socversions = {{"Short_SoC_version", "Ascend950"}, {"NpuArch", "3510"}}; | ||
| 503 | + string compile_info_string = R"({ | ||
| 504 | + "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1", | ||
| 505 | + "Intrinsic_fix_pipe_l0c2out": false, | ||
| 506 | + "Intrinsic_data_move_l12ub": true, | ||
| 507 | + "Intrinsic_data_move_l0c2ub": true, | ||
| 508 | + "Intrinsic_data_move_out2l1_nd2nz": false, | ||
| 509 | + "UB_SIZE": 196608, "L2_SIZE": 33554432, "L1_SIZE": 524288, | ||
| 510 | + "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072, | ||
| 511 | + "CORE_NUM": 48} | ||
| 512 | + })"; | ||
| 513 | + | ||
| 514 | + gert::StorageShape x_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 515 | + gert::StorageShape scale_shape = {{1, 2, 1}, {1, 2, 1}}; | ||
| 516 | + gert::StorageShape offset_shape = {{1, 2, 1}, {1, 2, 1}}; | ||
| 517 | + gert::StorageShape out_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 518 | + | ||
| 519 | + AscendAntiQuantV2CompileInfo compile_info; | ||
| 520 | + std::string op_type("AscendAntiQuantV2"); | ||
| 521 | + ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str()), nullptr); | ||
| 522 | + auto tiling_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling; | ||
| 523 | + auto tiling_parse_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling_parse; | ||
| 524 | + | ||
| 525 | + // tilingParseFunc simulate | ||
| 526 | + auto kernel_holder = | ||
| 527 | + gert::KernelRunContextFaker() | ||
| 528 | + .KernelIONum(2, 1) | ||
| 529 | + .Inputs({const_cast<char*>(compile_info_string.c_str()), reinterpret_cast<void*>(&platform_info)}) | ||
| 530 | + .Outputs({&compile_info}) | ||
| 531 | + .Build(); | ||
| 532 | + | ||
| 533 | + ASSERT_TRUE(kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->Init()); | ||
| 534 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 535 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 536 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 537 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes( | ||
| 538 | + "AICoreintrinsicDtypeMap", intrinsics); | ||
| 539 | + | ||
| 540 | + ASSERT_EQ(tiling_parse_func(kernel_holder.GetContext<gert::KernelContext>()), ge::GRAPH_SUCCESS); | ||
| 541 | + | ||
| 542 | + // tilingFunc simulate | ||
| 543 | + auto param = gert::TilingData::CreateCap(4096); | ||
| 544 | + auto workspace_size_holer = gert::ContinuousVector::Create<size_t>(16 * 1024 * 1024); | ||
| 545 | + auto ws_size = reinterpret_cast<gert::ContinuousVector*>(workspace_size_holer.get()); | ||
| 546 | + ASSERT_NE(param, nullptr); | ||
| 547 | + auto holder = gert::TilingContextFaker() | ||
| 548 | + .NodeIoNum(3, 1) | ||
| 549 | + .IrInstanceNum({1, 1, 1}) | ||
| 550 | + .InputShapes({&x_shape, &scale_shape, &offset_shape}) | ||
| 551 | + .OutputShapes({&out_shape}) | ||
| 552 | + .CompileInfo(&compile_info) | ||
| 553 | + .PlatformInfo(reinterpret_cast<char*>(&platform_info)) | ||
| 554 | + .NodeInputTd(0, ge::DT_INT4, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 555 | + .NodeInputTd(1, ge::DT_BF16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 556 | + .NodeInputTd(2, ge::DT_BF16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 557 | + .NodeOutputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 558 | + .NodeAttrs({ | ||
| 559 | + {"dst_type", Ops::NN::AnyValue::CreateFrom<int64_t>(1)}, | ||
| 560 | + {"sqrt_mode", Ops::NN::AnyValue::CreateFrom<bool>(false)} | ||
| 561 | + }) | ||
| 562 | + .TilingData(param.get()) | ||
| 563 | + .Workspace(ws_size) | ||
| 564 | + .Build(); | ||
| 565 | + | ||
| 566 | + gert::TilingContext* tiling_context = holder.GetContext<gert::TilingContext>(); | ||
| 567 | + ASSERT_NE(tiling_context->GetPlatformInfo(), nullptr); | ||
| 568 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 569 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 570 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 571 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics); | ||
| 572 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", socversions); | ||
| 573 | + | ||
| 574 | + EXPECT_EQ(tiling_func(tiling_context), ge::GRAPH_SUCCESS); | ||
| 575 | +} | ||
| 576 | + | ||
| 577 | +TEST_F(AscendAntiQuantV2Tiling, ascend_anti_quant_v2_tiling_per_head_950_7) | ||
| 578 | +{ | ||
| 579 | + // test int8, block cut -2 axis | ||
| 580 | + fe::PlatFormInfos platform_info; | ||
| 581 | + map<string, string> soc_infos; | ||
| 582 | + map<string, string> aicore_spec; | ||
| 583 | + map<string, string> intrinsics; | ||
| 584 | + InitPlatForm(platform_info, soc_infos, aicore_spec, intrinsics); | ||
| 585 | + map<string, string> socversions = {{"Short_SoC_version", "Ascend950"}, {"NpuArch", "3510"}}; | ||
| 586 | + string compile_info_string = R"({ | ||
| 587 | + "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1", | ||
| 588 | + "Intrinsic_fix_pipe_l0c2out": false, | ||
| 589 | + "Intrinsic_data_move_l12ub": true, | ||
| 590 | + "Intrinsic_data_move_l0c2ub": true, | ||
| 591 | + "Intrinsic_data_move_out2l1_nd2nz": false, | ||
| 592 | + "UB_SIZE": 196608, "L2_SIZE": 33554432, "L1_SIZE": 524288, | ||
| 593 | + "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072, | ||
| 594 | + "CORE_NUM": 48} | ||
| 595 | + })"; | ||
| 596 | + | ||
| 597 | + gert::StorageShape x_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 598 | + gert::StorageShape scale_shape = {{2}, {2}}; | ||
| 599 | + gert::StorageShape offset_shape = {{2}, {2}}; | ||
| 600 | + gert::StorageShape out_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 601 | + | ||
| 602 | + AscendAntiQuantV2CompileInfo compile_info; | ||
| 603 | + std::string op_type("AscendAntiQuantV2"); | ||
| 604 | + ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str()), nullptr); | ||
| 605 | + auto tiling_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling; | ||
| 606 | + auto tiling_parse_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling_parse; | ||
| 607 | + | ||
| 608 | + // tilingParseFunc simulate | ||
| 609 | + auto kernel_holder = | ||
| 610 | + gert::KernelRunContextFaker() | ||
| 611 | + .KernelIONum(2, 1) | ||
| 612 | + .Inputs({const_cast<char*>(compile_info_string.c_str()), reinterpret_cast<void*>(&platform_info)}) | ||
| 613 | + .Outputs({&compile_info}) | ||
| 614 | + .Build(); | ||
| 615 | + | ||
| 616 | + ASSERT_TRUE(kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->Init()); | ||
| 617 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 618 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 619 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 620 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes( | ||
| 621 | + "AICoreintrinsicDtypeMap", intrinsics); | ||
| 622 | + | ||
| 623 | + ASSERT_EQ(tiling_parse_func(kernel_holder.GetContext<gert::KernelContext>()), ge::GRAPH_SUCCESS); | ||
| 624 | + | ||
| 625 | + // tilingFunc simulate | ||
| 626 | + auto param = gert::TilingData::CreateCap(4096); | ||
| 627 | + auto workspace_size_holer = gert::ContinuousVector::Create<size_t>(16 * 1024 * 1024); | ||
| 628 | + auto ws_size = reinterpret_cast<gert::ContinuousVector*>(workspace_size_holer.get()); | ||
| 629 | + ASSERT_NE(param, nullptr); | ||
| 630 | + auto holder = gert::TilingContextFaker() | ||
| 631 | + .NodeIoNum(3, 1) | ||
| 632 | + .IrInstanceNum({1, 1, 1}) | ||
| 633 | + .InputShapes({&x_shape, &scale_shape, &offset_shape}) | ||
| 634 | + .OutputShapes({&out_shape}) | ||
| 635 | + .CompileInfo(&compile_info) | ||
| 636 | + .PlatformInfo(reinterpret_cast<char*>(&platform_info)) | ||
| 637 | + .NodeInputTd(0, ge::DT_INT8, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 638 | + .NodeInputTd(1, ge::DT_BF16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 639 | + .NodeInputTd(2, ge::DT_BF16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 640 | + .NodeOutputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 641 | + .NodeAttrs({ | ||
| 642 | + {"dst_type", Ops::NN::AnyValue::CreateFrom<int64_t>(1)}, | ||
| 643 | + {"sqrt_mode", Ops::NN::AnyValue::CreateFrom<bool>(false)} | ||
| 644 | + }) | ||
| 645 | + .TilingData(param.get()) | ||
| 646 | + .Workspace(ws_size) | ||
| 647 | + .Build(); | ||
| 648 | + | ||
| 649 | + gert::TilingContext* tiling_context = holder.GetContext<gert::TilingContext>(); | ||
| 650 | + ASSERT_NE(tiling_context->GetPlatformInfo(), nullptr); | ||
| 651 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 652 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 653 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 654 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics); | ||
| 655 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", socversions); | ||
| 656 | + | ||
| 657 | + EXPECT_EQ(tiling_func(tiling_context), ge::GRAPH_SUCCESS); | ||
| 658 | +} | ||
| 659 | + | ||
| 660 | +TEST_F(AscendAntiQuantV2Tiling, ascend_anti_quant_v2_tiling_per_head_no_offset_950_8) | ||
| 661 | +{ | ||
| 662 | + // test float8_e5m2, block cut -2 axis | ||
| 663 | + fe::PlatFormInfos platform_info; | ||
| 664 | + map<string, string> soc_infos; | ||
| 665 | + map<string, string> aicore_spec; | ||
| 666 | + map<string, string> intrinsics; | ||
| 667 | + InitPlatForm(platform_info, soc_infos, aicore_spec, intrinsics); | ||
| 668 | + map<string, string> socversions = {{"Short_SoC_version", "Ascend950"}, {"NpuArch", "3510"}}; | ||
| 669 | + string compile_info_string = R"({ | ||
| 670 | + "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1", | ||
| 671 | + "Intrinsic_fix_pipe_l0c2out": false, | ||
| 672 | + "Intrinsic_data_move_l12ub": true, | ||
| 673 | + "Intrinsic_data_move_l0c2ub": true, | ||
| 674 | + "Intrinsic_data_move_out2l1_nd2nz": false, | ||
| 675 | + "UB_SIZE": 196608, "L2_SIZE": 33554432, "L1_SIZE": 524288, | ||
| 676 | + "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072, | ||
| 677 | + "CORE_NUM": 48} | ||
| 678 | + })"; | ||
| 679 | + | ||
| 680 | + gert::StorageShape x_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 681 | + gert::StorageShape scale_shape = {{2}, {2}}; | ||
| 682 | + gert::StorageShape out_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 683 | + | ||
| 684 | + AscendAntiQuantV2CompileInfo compile_info; | ||
| 685 | + std::string op_type("AscendAntiQuantV2"); | ||
| 686 | + ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str()), nullptr); | ||
| 687 | + auto tiling_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling; | ||
| 688 | + auto tiling_parse_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling_parse; | ||
| 689 | + | ||
| 690 | + // tilingParseFunc simulate | ||
| 691 | + auto kernel_holder = | ||
| 692 | + gert::KernelRunContextFaker() | ||
| 693 | + .KernelIONum(2, 1) | ||
| 694 | + .Inputs({const_cast<char*>(compile_info_string.c_str()), reinterpret_cast<void*>(&platform_info)}) | ||
| 695 | + .Outputs({&compile_info}) | ||
| 696 | + .Build(); | ||
| 697 | + | ||
| 698 | + ASSERT_TRUE(kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->Init()); | ||
| 699 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 700 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 701 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 702 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes( | ||
| 703 | + "AICoreintrinsicDtypeMap", intrinsics); | ||
| 704 | + | ||
| 705 | + ASSERT_EQ(tiling_parse_func(kernel_holder.GetContext<gert::KernelContext>()), ge::GRAPH_SUCCESS); | ||
| 706 | + | ||
| 707 | + // tilingFunc simulate | ||
| 708 | + auto param = gert::TilingData::CreateCap(4096); | ||
| 709 | + auto workspace_size_holer = gert::ContinuousVector::Create<size_t>(16 * 1024 * 1024); | ||
| 710 | + auto ws_size = reinterpret_cast<gert::ContinuousVector*>(workspace_size_holer.get()); | ||
| 711 | + ASSERT_NE(param, nullptr); | ||
| 712 | + auto holder = gert::TilingContextFaker() | ||
| 713 | + .NodeIoNum(3, 1) | ||
| 714 | + .IrInstanceNum({1, 1, 0}) | ||
| 715 | + .InputShapes({&x_shape, &scale_shape}) | ||
| 716 | + .OutputShapes({&out_shape}) | ||
| 717 | + .CompileInfo(&compile_info) | ||
| 718 | + .PlatformInfo(reinterpret_cast<char*>(&platform_info)) | ||
| 719 | + .NodeInputTd(0, ge::DT_FLOAT8_E5M2, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 720 | + .NodeInputTd(1, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 721 | + .NodeOutputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 722 | + .NodeAttrs({ | ||
| 723 | + {"dst_type", Ops::NN::AnyValue::CreateFrom<int64_t>(1)}, | ||
| 724 | + {"sqrt_mode", Ops::NN::AnyValue::CreateFrom<bool>(false)} | ||
| 725 | + }) | ||
| 726 | + .TilingData(param.get()) | ||
| 727 | + .Workspace(ws_size) | ||
| 728 | + .Build(); | ||
| 729 | + | ||
| 730 | + gert::TilingContext* tiling_context = holder.GetContext<gert::TilingContext>(); | ||
| 731 | + ASSERT_NE(tiling_context->GetPlatformInfo(), nullptr); | ||
| 732 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 733 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 734 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 735 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics); | ||
| 736 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", socversions); | ||
| 737 | + | ||
| 738 | + EXPECT_EQ(tiling_func(tiling_context), ge::GRAPH_SUCCESS); | ||
| 739 | +} | ||
| 740 | + | ||
| 741 | +TEST_F(AscendAntiQuantV2Tiling, ascend_anti_quant_v2_tiling_950_error_shape_1) | ||
| 742 | +{ | ||
| 743 | + // test int4, blcok cut last axis | ||
| 744 | + fe::PlatFormInfos platform_info; | ||
| 745 | + map<string, string> soc_infos; | ||
| 746 | + map<string, string> aicore_spec; | ||
| 747 | + map<string, string> intrinsics; | ||
| 748 | + InitPlatForm(platform_info, soc_infos, aicore_spec, intrinsics); | ||
| 749 | + map<string, string> socversions = {{"Short_SoC_version", "Ascend950"}, {"NpuArch", "3510"}}; | ||
| 750 | + string compile_info_string = R"({ | ||
| 751 | + "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1", | ||
| 752 | + "Intrinsic_fix_pipe_l0c2out": false, | ||
| 753 | + "Intrinsic_data_move_l12ub": true, | ||
| 754 | + "Intrinsic_data_move_l0c2ub": true, | ||
| 755 | + "Intrinsic_data_move_out2l1_nd2nz": false, | ||
| 756 | + "UB_SIZE": 196608, "L2_SIZE": 33554432, "L1_SIZE": 524288, | ||
| 757 | + "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072, | ||
| 758 | + "CORE_NUM": 48} | ||
| 759 | + })"; | ||
| 760 | + | ||
| 761 | + gert::StorageShape x_shape = {{4, 1280, 1021}, {4, 1280, 1021}}; | ||
| 762 | + gert::StorageShape scale_shape = {{1}, {1}}; | ||
| 763 | + gert::StorageShape offset_shape = {{1}, {1}}; | ||
| 764 | + gert::StorageShape out_shape = {{4, 1280, 1021}, {4, 1280, 1021}}; | ||
| 765 | + | ||
| 766 | + AscendAntiQuantV2CompileInfo compile_info; | ||
| 767 | + std::string op_type("AscendAntiQuantV2"); | ||
| 768 | + ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str()), nullptr); | ||
| 769 | + auto tiling_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling; | ||
| 770 | + auto tiling_parse_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling_parse; | ||
| 771 | + | ||
| 772 | + // tilingParseFunc simulate | ||
| 773 | + auto kernel_holder = | ||
| 774 | + gert::KernelRunContextFaker() | ||
| 775 | + .KernelIONum(2, 1) | ||
| 776 | + .Inputs({const_cast<char*>(compile_info_string.c_str()), reinterpret_cast<void*>(&platform_info)}) | ||
| 777 | + .Outputs({&compile_info}) | ||
| 778 | + .Build(); | ||
| 779 | + | ||
| 780 | + ASSERT_TRUE(kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->Init()); | ||
| 781 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 782 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 783 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 784 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes( | ||
| 785 | + "AICoreintrinsicDtypeMap", intrinsics); | ||
| 786 | + | ||
| 787 | + ASSERT_EQ(tiling_parse_func(kernel_holder.GetContext<gert::KernelContext>()), ge::GRAPH_SUCCESS); | ||
| 788 | + | ||
| 789 | + // tilingFunc simulate | ||
| 790 | + auto param = gert::TilingData::CreateCap(4096); | ||
| 791 | + auto workspace_size_holer = gert::ContinuousVector::Create<size_t>(16 * 1024 * 1024); | ||
| 792 | + auto ws_size = reinterpret_cast<gert::ContinuousVector*>(workspace_size_holer.get()); | ||
| 793 | + ASSERT_NE(param, nullptr); | ||
| 794 | + auto holder = gert::TilingContextFaker() | ||
| 795 | + .NodeIoNum(3, 1) | ||
| 796 | + .IrInstanceNum({1, 1, 1}) | ||
| 797 | + .InputShapes({&x_shape, &scale_shape, &offset_shape}) | ||
| 798 | + .OutputShapes({&out_shape}) | ||
| 799 | + .CompileInfo(&compile_info) | ||
| 800 | + .PlatformInfo(reinterpret_cast<char*>(&platform_info)) | ||
| 801 | + .NodeInputTd(0, ge::DT_INT4, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 802 | + .NodeInputTd(1, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 803 | + .NodeInputTd(2, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 804 | + .NodeOutputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 805 | + .NodeAttrs({ | ||
| 806 | + {"dst_type", Ops::NN::AnyValue::CreateFrom<int64_t>(1)}, | ||
| 807 | + {"sqrt_mode", Ops::NN::AnyValue::CreateFrom<bool>(true)} | ||
| 808 | + }) | ||
| 809 | + .TilingData(param.get()) | ||
| 810 | + .Workspace(ws_size) | ||
| 811 | + .Build(); | ||
| 812 | + | ||
| 813 | + gert::TilingContext* tiling_context = holder.GetContext<gert::TilingContext>(); | ||
| 814 | + ASSERT_NE(tiling_context->GetPlatformInfo(), nullptr); | ||
| 815 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 816 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 817 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 818 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics); | ||
| 819 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", socversions); | ||
| 820 | + | ||
| 821 | + EXPECT_EQ(tiling_func(tiling_context), ge::GRAPH_FAILED); | ||
| 822 | +} | ||
| 823 | + | ||
| 824 | +TEST_F(AscendAntiQuantV2Tiling, ascend_anti_quant_v2_tiling_950_error_shape_2) | ||
| 825 | +{ | ||
| 826 | + // test hifloat8, blcok cut last axis | ||
| 827 | + fe::PlatFormInfos platform_info; | ||
| 828 | + map<string, string> soc_infos; | ||
| 829 | + map<string, string> aicore_spec; | ||
| 830 | + map<string, string> intrinsics; | ||
| 831 | + InitPlatForm(platform_info, soc_infos, aicore_spec, intrinsics); | ||
| 832 | + map<string, string> socversions = {{"Short_SoC_version", "Ascend950"}, {"NpuArch", "3510"}}; | ||
| 833 | + map<string, string> npuarchs = {{"NpuArch", "3510"}}; | ||
| 834 | + string compile_info_string = R"({ | ||
| 835 | + "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1", | ||
| 836 | + "Intrinsic_fix_pipe_l0c2out": false, | ||
| 837 | + "Intrinsic_data_move_l12ub": true, | ||
| 838 | + "Intrinsic_data_move_l0c2ub": true, | ||
| 839 | + "Intrinsic_data_move_out2l1_nd2nz": false, | ||
| 840 | + "UB_SIZE": 196608, "L2_SIZE": 33554432, "L1_SIZE": 524288, | ||
| 841 | + "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072, | ||
| 842 | + "CORE_NUM": 48} | ||
| 843 | + })"; | ||
| 844 | + | ||
| 845 | + gert::StorageShape x_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 846 | + gert::StorageShape scale_shape = {{10}, {10}}; | ||
| 847 | + gert::StorageShape offset_shape = {{10}, {10}}; | ||
| 848 | + gert::StorageShape out_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 849 | + | ||
| 850 | + AscendAntiQuantV2CompileInfo compile_info; | ||
| 851 | + std::string op_type("AscendAntiQuantV2"); | ||
| 852 | + ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str()), nullptr); | ||
| 853 | + auto tiling_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling; | ||
| 854 | + auto tiling_parse_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling_parse; | ||
| 855 | + | ||
| 856 | + // tilingParseFunc simulate | ||
| 857 | + auto kernel_holder = | ||
| 858 | + gert::KernelRunContextFaker() | ||
| 859 | + .KernelIONum(2, 1) | ||
| 860 | + .Inputs({const_cast<char*>(compile_info_string.c_str()), reinterpret_cast<void*>(&platform_info)}) | ||
| 861 | + .Outputs({&compile_info}) | ||
| 862 | + .Build(); | ||
| 863 | + | ||
| 864 | + ASSERT_TRUE(kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->Init()); | ||
| 865 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 866 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 867 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 868 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes( | ||
| 869 | + "AICoreintrinsicDtypeMap", intrinsics); | ||
| 870 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("version", npuarchs); | ||
| 871 | + | ||
| 872 | + ASSERT_EQ(tiling_parse_func(kernel_holder.GetContext<gert::KernelContext>()), ge::GRAPH_SUCCESS); | ||
| 873 | + | ||
| 874 | + // tilingFunc simulate | ||
| 875 | + auto param = gert::TilingData::CreateCap(4096); | ||
| 876 | + auto workspace_size_holer = gert::ContinuousVector::Create<size_t>(16 * 1024 * 1024); | ||
| 877 | + auto ws_size = reinterpret_cast<gert::ContinuousVector*>(workspace_size_holer.get()); | ||
| 878 | + ASSERT_NE(param, nullptr); | ||
| 879 | + auto holder = gert::TilingContextFaker() | ||
| 880 | + .NodeIoNum(3, 1) | ||
| 881 | + .IrInstanceNum({1, 1, 1}) | ||
| 882 | + .InputShapes({&x_shape, &scale_shape, &offset_shape}) | ||
| 883 | + .OutputShapes({&out_shape}) | ||
| 884 | + .CompileInfo(&compile_info) | ||
| 885 | + .PlatformInfo(reinterpret_cast<char*>(&platform_info)) | ||
| 886 | + .NodeInputTd(0, ge::DT_HIFLOAT8, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 887 | + .NodeInputTd(1, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 888 | + .NodeInputTd(2, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 889 | + .NodeOutputTd(0, ge::DT_BF16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 890 | + .NodeAttrs({ | ||
| 891 | + {"dst_type", Ops::NN::AnyValue::CreateFrom<int64_t>(27)}, | ||
| 892 | + {"sqrt_mode", Ops::NN::AnyValue::CreateFrom<bool>(false)} | ||
| 893 | + }) | ||
| 894 | + .TilingData(param.get()) | ||
| 895 | + .Workspace(ws_size) | ||
| 896 | + .Build(); | ||
| 897 | + | ||
| 898 | + gert::TilingContext* tiling_context = holder.GetContext<gert::TilingContext>(); | ||
| 899 | + ASSERT_NE(tiling_context->GetPlatformInfo(), nullptr); | ||
| 900 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 901 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 902 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 903 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics); | ||
| 904 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", socversions); | ||
| 905 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", npuarchs); | ||
| 906 | + | ||
| 907 | + EXPECT_EQ(tiling_func(tiling_context), ge::GRAPH_FAILED); | ||
| 908 | +} | ||
| 909 | + | ||
| 910 | +TEST_F(AscendAntiQuantV2Tiling, ascend_anti_quant_v2_tiling_950_error_shape_3) | ||
| 911 | +{ | ||
| 912 | + // test float8_e5m2, blcok cut last axis | ||
| 913 | + fe::PlatFormInfos platform_info; | ||
| 914 | + map<string, string> soc_infos; | ||
| 915 | + map<string, string> aicore_spec; | ||
| 916 | + map<string, string> intrinsics; | ||
| 917 | + InitPlatForm(platform_info, soc_infos, aicore_spec, intrinsics); | ||
| 918 | + map<string, string> socversions = {{"Short_SoC_version", "Ascend950"}, {"NpuArch", "3510"}}; | ||
| 919 | + map<string, string> npuarchs = {{"NpuArch", "3510"}}; | ||
| 920 | + string compile_info_string = R"({ | ||
| 921 | + "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1", | ||
| 922 | + "Intrinsic_fix_pipe_l0c2out": false, | ||
| 923 | + "Intrinsic_data_move_l12ub": true, | ||
| 924 | + "Intrinsic_data_move_l0c2ub": true, | ||
| 925 | + "Intrinsic_data_move_out2l1_nd2nz": false, | ||
| 926 | + "UB_SIZE": 196608, "L2_SIZE": 33554432, "L1_SIZE": 524288, | ||
| 927 | + "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072, | ||
| 928 | + "CORE_NUM": 48} | ||
| 929 | + })"; | ||
| 930 | + | ||
| 931 | + gert::StorageShape x_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 932 | + gert::StorageShape scale_shape = {{2, 10240}, {2, 10240}}; | ||
| 933 | + gert::StorageShape offset_shape = {{2, 10240}, {2, 10240}}; | ||
| 934 | + gert::StorageShape out_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 935 | + | ||
| 936 | + AscendAntiQuantV2CompileInfo compile_info; | ||
| 937 | + std::string op_type("AscendAntiQuantV2"); | ||
| 938 | + ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str()), nullptr); | ||
| 939 | + auto tiling_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling; | ||
| 940 | + auto tiling_parse_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling_parse; | ||
| 941 | + | ||
| 942 | + // tilingParseFunc simulate | ||
| 943 | + auto kernel_holder = | ||
| 944 | + gert::KernelRunContextFaker() | ||
| 945 | + .KernelIONum(2, 1) | ||
| 946 | + .Inputs({const_cast<char*>(compile_info_string.c_str()), reinterpret_cast<void*>(&platform_info)}) | ||
| 947 | + .Outputs({&compile_info}) | ||
| 948 | + .Build(); | ||
| 949 | + | ||
| 950 | + ASSERT_TRUE(kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->Init()); | ||
| 951 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 952 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 953 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 954 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes( | ||
| 955 | + "AICoreintrinsicDtypeMap", intrinsics); | ||
| 956 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("version", npuarchs); | ||
| 957 | + | ||
| 958 | + ASSERT_EQ(tiling_parse_func(kernel_holder.GetContext<gert::KernelContext>()), ge::GRAPH_SUCCESS); | ||
| 959 | + | ||
| 960 | + // tilingFunc simulate | ||
| 961 | + auto param = gert::TilingData::CreateCap(4096); | ||
| 962 | + auto workspace_size_holer = gert::ContinuousVector::Create<size_t>(16 * 1024 * 1024); | ||
| 963 | + auto ws_size = reinterpret_cast<gert::ContinuousVector*>(workspace_size_holer.get()); | ||
| 964 | + ASSERT_NE(param, nullptr); | ||
| 965 | + auto holder = gert::TilingContextFaker() | ||
| 966 | + .NodeIoNum(3, 1) | ||
| 967 | + .IrInstanceNum({1, 1, 1}) | ||
| 968 | + .InputShapes({&x_shape, &scale_shape, &offset_shape}) | ||
| 969 | + .OutputShapes({&out_shape}) | ||
| 970 | + .CompileInfo(&compile_info) | ||
| 971 | + .PlatformInfo(reinterpret_cast<char*>(&platform_info)) | ||
| 972 | + .NodeInputTd(0, ge::DT_FLOAT8_E5M2, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 973 | + .NodeInputTd(1, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 974 | + .NodeInputTd(2, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 975 | + .NodeOutputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 976 | + .NodeAttrs({ | ||
| 977 | + {"dst_type", Ops::NN::AnyValue::CreateFrom<int64_t>(1)}, | ||
| 978 | + {"sqrt_mode", Ops::NN::AnyValue::CreateFrom<bool>(false)} | ||
| 979 | + }) | ||
| 980 | + .TilingData(param.get()) | ||
| 981 | + .Workspace(ws_size) | ||
| 982 | + .Build(); | ||
| 983 | + | ||
| 984 | + gert::TilingContext* tiling_context = holder.GetContext<gert::TilingContext>(); | ||
| 985 | + ASSERT_NE(tiling_context->GetPlatformInfo(), nullptr); | ||
| 986 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 987 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 988 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 989 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics); | ||
| 990 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", socversions); | ||
| 991 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", npuarchs); | ||
| 992 | + | ||
| 993 | + EXPECT_EQ(tiling_func(tiling_context), ge::GRAPH_FAILED); | ||
| 994 | +} | ||
| 995 | + | ||
| 996 | +TEST_F(AscendAntiQuantV2Tiling, ascend_anti_quant_v2_tiling_950_error_sqrtMode_4) | ||
| 997 | +{ | ||
| 998 | + // test float8_e5m2, blcok cut last axis | ||
| 999 | + fe::PlatFormInfos platform_info; | ||
| 1000 | + map<string, string> soc_infos; | ||
| 1001 | + map<string, string> aicore_spec; | ||
| 1002 | + map<string, string> intrinsics; | ||
| 1003 | + InitPlatForm(platform_info, soc_infos, aicore_spec, intrinsics); | ||
| 1004 | + map<string, string> socversions = {{"Short_SoC_version", "Ascend950"}, {"NpuArch", "3510"}}; | ||
| 1005 | + map<string, string> npuarchs = {{"NpuArch", "3510"}}; | ||
| 1006 | + string compile_info_string = R"({ | ||
| 1007 | + "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1", | ||
| 1008 | + "Intrinsic_fix_pipe_l0c2out": false, | ||
| 1009 | + "Intrinsic_data_move_l12ub": true, | ||
| 1010 | + "Intrinsic_data_move_l0c2ub": true, | ||
| 1011 | + "Intrinsic_data_move_out2l1_nd2nz": false, | ||
| 1012 | + "UB_SIZE": 196608, "L2_SIZE": 33554432, "L1_SIZE": 524288, | ||
| 1013 | + "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072, | ||
| 1014 | + "CORE_NUM": 48} | ||
| 1015 | + })"; | ||
| 1016 | + | ||
| 1017 | + gert::StorageShape x_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 1018 | + gert::StorageShape scale_shape = {{1, 10240}, {1, 10240}}; | ||
| 1019 | + gert::StorageShape offset_shape = {{1, 10240}, {1, 10240}}; | ||
| 1020 | + gert::StorageShape out_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 1021 | + | ||
| 1022 | + AscendAntiQuantV2CompileInfo compile_info; | ||
| 1023 | + std::string op_type("AscendAntiQuantV2"); | ||
| 1024 | + ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str()), nullptr); | ||
| 1025 | + auto tiling_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling; | ||
| 1026 | + auto tiling_parse_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling_parse; | ||
| 1027 | + | ||
| 1028 | + // tilingParseFunc simulate | ||
| 1029 | + auto kernel_holder = | ||
| 1030 | + gert::KernelRunContextFaker() | ||
| 1031 | + .KernelIONum(2, 1) | ||
| 1032 | + .Inputs({const_cast<char*>(compile_info_string.c_str()), reinterpret_cast<void*>(&platform_info)}) | ||
| 1033 | + .Outputs({&compile_info}) | ||
| 1034 | + .Build(); | ||
| 1035 | + | ||
| 1036 | + ASSERT_TRUE(kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->Init()); | ||
| 1037 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 1038 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 1039 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 1040 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes( | ||
| 1041 | + "AICoreintrinsicDtypeMap", intrinsics); | ||
| 1042 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("version", npuarchs); | ||
| 1043 | + | ||
| 1044 | + ASSERT_EQ(tiling_parse_func(kernel_holder.GetContext<gert::KernelContext>()), ge::GRAPH_SUCCESS); | ||
| 1045 | + | ||
| 1046 | + // tilingFunc simulate | ||
| 1047 | + auto param = gert::TilingData::CreateCap(4096); | ||
| 1048 | + auto workspace_size_holer = gert::ContinuousVector::Create<size_t>(16 * 1024 * 1024); | ||
| 1049 | + auto ws_size = reinterpret_cast<gert::ContinuousVector*>(workspace_size_holer.get()); | ||
| 1050 | + ASSERT_NE(param, nullptr); | ||
| 1051 | + auto holder = gert::TilingContextFaker() | ||
| 1052 | + .NodeIoNum(3, 1) | ||
| 1053 | + .IrInstanceNum({1, 1, 1}) | ||
| 1054 | + .InputShapes({&x_shape, &scale_shape, &offset_shape}) | ||
| 1055 | + .OutputShapes({&out_shape}) | ||
| 1056 | + .CompileInfo(&compile_info) | ||
| 1057 | + .PlatformInfo(reinterpret_cast<char*>(&platform_info)) | ||
| 1058 | + .NodeInputTd(0, ge::DT_FLOAT8_E5M2, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 1059 | + .NodeInputTd(1, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 1060 | + .NodeInputTd(2, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 1061 | + .NodeOutputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 1062 | + .NodeAttrs({ | ||
| 1063 | + {"dst_type", Ops::NN::AnyValue::CreateFrom<int64_t>(1)}, | ||
| 1064 | + {"sqrt_mode", Ops::NN::AnyValue::CreateFrom<bool>(true)} | ||
| 1065 | + }) | ||
| 1066 | + .TilingData(param.get()) | ||
| 1067 | + .Workspace(ws_size) | ||
| 1068 | + .Build(); | ||
| 1069 | + | ||
| 1070 | + gert::TilingContext* tiling_context = holder.GetContext<gert::TilingContext>(); | ||
| 1071 | + ASSERT_NE(tiling_context->GetPlatformInfo(), nullptr); | ||
| 1072 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 1073 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 1074 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 1075 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics); | ||
| 1076 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", socversions); | ||
| 1077 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", npuarchs); | ||
| 1078 | + | ||
| 1079 | + EXPECT_EQ(tiling_func(tiling_context), ge::GRAPH_FAILED); | ||
| 1080 | +} | ||
| 1081 | + | ||
| 1082 | +TEST_F(AscendAntiQuantV2Tiling, ascend_anti_quant_v2_tiling_950_error_Float_4) | ||
| 1083 | +{ | ||
| 1084 | + // test float8_e5m2, blcok cut last axis | ||
| 1085 | + fe::PlatFormInfos platform_info; | ||
| 1086 | + map<string, string> soc_infos; | ||
| 1087 | + map<string, string> aicore_spec; | ||
| 1088 | + map<string, string> intrinsics; | ||
| 1089 | + InitPlatForm(platform_info, soc_infos, aicore_spec, intrinsics); | ||
| 1090 | + map<string, string> socversions = {{"Short_SoC_version", "Ascend950"}, {"NpuArch", "3510"}}; | ||
| 1091 | + map<string, string> npuarchs = {{"NpuArch", "3510"}}; | ||
| 1092 | + string compile_info_string = R"({ | ||
| 1093 | + "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1", | ||
| 1094 | + "Intrinsic_fix_pipe_l0c2out": false, | ||
| 1095 | + "Intrinsic_data_move_l12ub": true, | ||
| 1096 | + "Intrinsic_data_move_l0c2ub": true, | ||
| 1097 | + "Intrinsic_data_move_out2l1_nd2nz": false, | ||
| 1098 | + "UB_SIZE": 196608, "L2_SIZE": 33554432, "L1_SIZE": 524288, | ||
| 1099 | + "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072, | ||
| 1100 | + "CORE_NUM": 48} | ||
| 1101 | + })"; | ||
| 1102 | + | ||
| 1103 | + gert::StorageShape x_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 1104 | + gert::StorageShape scale_shape = {{1, 10240}, {1, 10240}}; | ||
| 1105 | + gert::StorageShape offset_shape = {{1, 10240}, {1, 10240}}; | ||
| 1106 | + gert::StorageShape out_shape = {{4, 2, 10240}, {4, 2, 10240}}; | ||
| 1107 | + | ||
| 1108 | + AscendAntiQuantV2CompileInfo compile_info; | ||
| 1109 | + std::string op_type("AscendAntiQuantV2"); | ||
| 1110 | + ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str()), nullptr); | ||
| 1111 | + auto tiling_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling; | ||
| 1112 | + auto tiling_parse_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling_parse; | ||
| 1113 | + | ||
| 1114 | + // tilingParseFunc simulate | ||
| 1115 | + auto kernel_holder = | ||
| 1116 | + gert::KernelRunContextFaker() | ||
| 1117 | + .KernelIONum(2, 1) | ||
| 1118 | + .Inputs({const_cast<char*>(compile_info_string.c_str()), reinterpret_cast<void*>(&platform_info)}) | ||
| 1119 | + .Outputs({&compile_info}) | ||
| 1120 | + .Build(); | ||
| 1121 | + | ||
| 1122 | + ASSERT_TRUE(kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->Init()); | ||
| 1123 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 1124 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 1125 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 1126 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes( | ||
| 1127 | + "AICoreintrinsicDtypeMap", intrinsics); | ||
| 1128 | + kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("version", npuarchs); | ||
| 1129 | + | ||
| 1130 | + ASSERT_EQ(tiling_parse_func(kernel_holder.GetContext<gert::KernelContext>()), ge::GRAPH_SUCCESS); | ||
| 1131 | + | ||
| 1132 | + // tilingFunc simulate | ||
| 1133 | + auto param = gert::TilingData::CreateCap(4096); | ||
| 1134 | + auto workspace_size_holer = gert::ContinuousVector::Create<size_t>(16 * 1024 * 1024); | ||
| 1135 | + auto ws_size = reinterpret_cast<gert::ContinuousVector*>(workspace_size_holer.get()); | ||
| 1136 | + ASSERT_NE(param, nullptr); | ||
| 1137 | + auto holder = gert::TilingContextFaker() | ||
| 1138 | + .NodeIoNum(3, 1) | ||
| 1139 | + .IrInstanceNum({1, 1, 1}) | ||
| 1140 | + .InputShapes({&x_shape, &scale_shape, &offset_shape}) | ||
| 1141 | + .OutputShapes({&out_shape}) | ||
| 1142 | + .CompileInfo(&compile_info) | ||
| 1143 | + .PlatformInfo(reinterpret_cast<char*>(&platform_info)) | ||
| 1144 | + .NodeInputTd(0, ge::DT_FLOAT8_E5M2, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 1145 | + .NodeInputTd(1, ge::DT_BF16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 1146 | + .NodeInputTd(2, ge::DT_BF16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 1147 | + .NodeOutputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND) | ||
| 1148 | + .NodeAttrs({ | ||
| 1149 | + {"dst_type", Ops::NN::AnyValue::CreateFrom<int64_t>(1)}, | ||
| 1150 | + {"sqrt_mode", Ops::NN::AnyValue::CreateFrom<bool>(true)} | ||
| 1151 | + }) | ||
| 1152 | + .TilingData(param.get()) | ||
| 1153 | + .Workspace(ws_size) | ||
| 1154 | + .Build(); | ||
| 1155 | + | ||
| 1156 | + gert::TilingContext* tiling_context = holder.GetContext<gert::TilingContext>(); | ||
| 1157 | + ASSERT_NE(tiling_context->GetPlatformInfo(), nullptr); | ||
| 1158 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos); | ||
| 1159 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec); | ||
| 1160 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore"); | ||
| 1161 | + holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics); | ||
| 1162 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", socversions); | ||
| 1163 | + tiling_context->GetPlatformInfo()->SetPlatformRes("version", npuarchs); | ||
| 1164 | + | ||
| 1165 | + EXPECT_EQ(tiling_func(tiling_context), ge::GRAPH_FAILED); | ||
| 1166 | +} | ||
| @@ -0,0 +1,94 @@ | |||
| 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 test_ascend_anti_quant_v2.cpp | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | +using namespace std; | ||
| 27 | + | ||
| 28 | +extern "C" __global__ __aicore__ void ascend_anti_quant_v2( | ||
| 29 | + GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y, GM_ADDR workspace, GM_ADDR tiling); | ||
| 30 | + | ||
| 31 | +class ascend_anti_quant_v2_test : public testing::Test { | ||
| 32 | +protected: | ||
| 33 | + static void SetUpTestCase() | ||
| 34 | + { | ||
| 35 | + cout << "ascend_anti_quant_v2_test SetUp\n" << endl; | ||
| 36 | + } | ||
| 37 | + static void TearDownTestCase() | ||
| 38 | + { | ||
| 39 | + cout << "ascend_anti_quant_v2_test TearDown\n" << endl; | ||
| 40 | + } | ||
| 41 | +}; | ||
| 42 | + | ||
| 43 | +TEST_F(ascend_anti_quant_v2_test, test_case_100) | ||
| 44 | +{ | ||
| 45 | + size_t inputXSize = 128 * 512 * sizeof(hifloat8_t); | ||
| 46 | + size_t inputScaleSize = 512 * sizeof(float); | ||
| 47 | + size_t inputOffsetSize = 512 * sizeof(float); | ||
| 48 | + size_t outputYSize = 128 * 512 * sizeof(half); | ||
| 49 | + size_t tiling_data_size = sizeof(AscendAntiQuantV2TilingData); | ||
| 50 | + uint32_t blockDim = 2; | ||
| 51 | + | ||
| 52 | + uint8_t* x = (uint8_t*)AscendC::GmAlloc(inputXSize); | ||
| 53 | + uint8_t* scale = (uint8_t*)AscendC::GmAlloc(inputScaleSize); | ||
| 54 | + uint8_t* offset = (uint8_t*)AscendC::GmAlloc(inputOffsetSize); | ||
| 55 | + uint8_t* y = (uint8_t*)AscendC::GmAlloc(outputYSize); | ||
| 56 | + | ||
| 57 | + uint8_t* workSpace = (uint8_t*)AscendC::GmAlloc(1024 * 1024 * 16); | ||
| 58 | + uint8_t* tiling = (uint8_t*)AscendC::GmAlloc(tiling_data_size); | ||
| 59 | + | ||
| 60 | + char* path_ = get_current_dir_name(); | ||
| 61 | + string path(path_); | ||
| 62 | + | ||
| 63 | + AscendC::SetKernelMode(KernelMode::AIV_MODE); | ||
| 64 | + AscendAntiQuantV2TilingData* tilingDatafromBin = reinterpret_cast<AscendAntiQuantV2TilingData*>(tiling); | ||
| 65 | + | ||
| 66 | + tilingDatafromBin->numCore = 43; | ||
| 67 | + tilingDatafromBin->blockAxis = 0; | ||
| 68 | + tilingDatafromBin->dim0 = 128; | ||
| 69 | + tilingDatafromBin->dim1 = 512; | ||
| 70 | + tilingDatafromBin->dim2 = 1; | ||
| 71 | + tilingDatafromBin->blockFactor = 3; | ||
| 72 | + tilingDatafromBin->blockTailFactor = 2; | ||
| 73 | + tilingDatafromBin->baseN = 3; | ||
| 74 | + tilingDatafromBin->baseLen = 512; | ||
| 75 | + tilingDatafromBin->hasOffset = 1; | ||
| 76 | + tilingDatafromBin->sqrtMode = 1; | ||
| 77 | + | ||
| 78 | + ICPU_SET_TILING_KEY(13); | ||
| 79 | + | ||
| 80 | + auto ascend_anti_quant_v2_kernel = [](GM_ADDR x, GM_ADDR scale, GM_ADDR offset, GM_ADDR y, | ||
| 81 | + GM_ADDR workSpace, GM_ADDR tiling) { | ||
| 82 | + ::ascend_anti_quant_v2<1, 1, 1>(x, scale, offset, y, workSpace, tiling); | ||
| 83 | + }; | ||
| 84 | + ICPU_RUN_KF( | ||
| 85 | + ascend_anti_quant_v2_kernel, blockDim, x, scale, offset, y, workSpace, tiling); | ||
| 86 | + | ||
| 87 | + AscendC::GmFree(x); | ||
| 88 | + AscendC::GmFree(scale); | ||
| 89 | + AscendC::GmFree(offset); | ||
| 90 | + AscendC::GmFree(y); | ||
| 91 | + AscendC::GmFree(workSpace); | ||
| 92 | + AscendC::GmFree(tilingDatafromBin); | ||
| 93 | + free(path_); | ||
| 94 | +} | ||
| @@ -535,6 +535,7 @@ | |||
| 535 | {"name":"AscendQuant", "compute_units": ["ascend950"], "auto_sync": false, "impl_mode": "", "compile_options": {"ascend950": ["-mllvm -cce-aicore-dcci-before-kernel-end=false"]}}, | 535 | {"name":"AscendQuant", "compute_units": ["ascend950"], "auto_sync": false, "impl_mode": "", "compile_options": {"ascend950": ["-mllvm -cce-aicore-dcci-before-kernel-end=false"]}}, |
| 536 | {"name":"Quantize", "compute_units": ["ascend950"], "auto_sync": false, "impl_mode": "", "compile_options": {"ascend950": ["-mllvm -cce-aicore-dcci-before-kernel-end=false"]}}, | 536 | {"name":"Quantize", "compute_units": ["ascend950"], "auto_sync": false, "impl_mode": "", "compile_options": {"ascend950": ["-mllvm -cce-aicore-dcci-before-kernel-end=false"]}}, |
| 537 | {"name":"AscendQuantV2", "compute_units": ["ascend310p", "ascend910b", "ascend910_93", "ascend950", "kirinx90", "kirin9030"], "auto_sync": false, "compile_options": {"ascend950": ["-mllvm -cce-aicore-dcci-before-kernel-end=false"]}}, | 537 | {"name":"AscendQuantV2", "compute_units": ["ascend310p", "ascend910b", "ascend910_93", "ascend950", "kirinx90", "kirin9030"], "auto_sync": false, "compile_options": {"ascend950": ["-mllvm -cce-aicore-dcci-before-kernel-end=false"]}}, |
| 538 | + {"name":"AscendAntiQuantV2", "compute_units": ["ascend950"], "auto_sync": false, "compile_options": {"ascend950": ["-mllvm -cce-aicore-dcci-before-kernel-end=false"]}}, | ||
| 538 | {"name":"QuantUpdateScatter", "compute_units": ["ascend950"], "auto_sync": false, "impl_mode": "", "compile_options": {"ascend950": ["-mllvm -cce-aicore-dcci-before-kernel-end=false"]}}, | 539 | {"name":"QuantUpdateScatter", "compute_units": ["ascend950"], "auto_sync": false, "impl_mode": "", "compile_options": {"ascend950": ["-mllvm -cce-aicore-dcci-before-kernel-end=false"]}}, |
| 539 | {"name":"MSELossV2", "compute_units": ["ascend310p", "ascend910b", "ascend910_93", "ascend950"], "auto_sync" : true}, | 540 | {"name":"MSELossV2", "compute_units": ["ascend310p", "ascend910b", "ascend910_93", "ascend950"], "auto_sync" : true}, |
| 540 | {"name":"BinaryCrossEntropyGrad", "compute_units": ["ascend950"], "auto_sync" : false, "impl_mode": "", "compile_options": {"ascend950": ["-mllvm -cce-aicore-dcci-before-kernel-end=false"]}}, | 541 | {"name":"BinaryCrossEntropyGrad", "compute_units": ["ascend950"], "auto_sync" : false, "impl_mode": "", "compile_options": {"ascend950": ["-mllvm -cce-aicore-dcci-before-kernel-end=false"]}}, |


算子参数说明解释的是quant/ascend_anti_quant_v2/op_host/ascend_anti_quant_v2_def.cpp里参数含义