已合并
index_fill_d index_put_v2 grouped_dynamic_mx_quant update #524
daiwei18创建于 2025年12月28日
index_fill_d index_put_v2 grouped_dynamic_mx_quant update #524
已合并
daiwei18创建于 2025年12月28日
88 个文件变更+8375-708
Mindex/index_fill_d/CMakeLists.txt+10-13
@@ -1,19 +1,16 @@
1# ----------------------------------------------------------------------------1# -----------------------------------------------------------------------------------------------------------
2# Copyright (c) 2025 Huawei Technologies Co., Ltd.2# Copyright (c) 2025 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.
6# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8# See LICENSE in the root of the software repository for the full text of the License.
9# ----------------------------------------------------------------------------9# -----------------------------------------------------------------------------------------------------------
10 10 
11file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)11 
12if(NOT ENABLE_TEST AND NOT BENCHMARK)12# 设置算子定义时支持的芯片类型
13 list(REMOVE_ITEM CURRENT_DIRS tests)13set(SUPPORT_COMPUTE_UNIT "ascend910_95")
14endif()14# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译
15foreach(SUB_DIR ${CURRENT_DIRS})15set(SUPPORT_TILING_DIR "arch35")
16 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")16add_modules_sources(HOSTNAME ${OPHOST_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR} OPTYPE index_fill_d ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE)
17 add_subdirectory(${SUB_DIR})
18 endif()
19endforeach()
Mindex/index_fill_d/README.md+100-1
@@ -1,3 +1,102 @@
1# IndexFillD1# IndexFillD
2 2 
3本目录仅包含IndexFillD算子对应的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 800I A2 推理产品/A200I A2 Box 异构组件</term> | √ |
10 
11## 功能说明
12 
13- 接口功能:沿输入self的给定轴dim,将index指定位置的值使用value进行替换。
14- 示例:
15输入self为:
16 
17 &emsp;&emsp;[[1, 2, 3],
18
19 &emsp;&emsp;&nbsp;[4, 5, 6],
20
21 &emsp;&emsp;&nbsp;[7, 8, 9]]
22
23 若dim = 0,index = [0, 2],value = 0时,算子的计算结果为:
24 
25 &emsp;&emsp;[[0, 0, 0],
26
27 &emsp;&emsp;&nbsp;[4, 5, 6],
28 
29 &emsp;&emsp;&nbsp;[0, 0, 0]]
30
31 若dim = 1,index = [0, 2],value = 0时,算子的计算结果为:
32 
33 &emsp;&emsp;[[0, 2, 0],
34
35 &emsp;&emsp;&nbsp;[0, 5, 0],
36 
37 &emsp;&emsp;&nbsp;[0, 8, 0]]
38 
39## 参数说明
40 
41 
42<table style="undefined;table-layout: fixed; width: 980px"><colgroup>
43 <col style="width: 100px">
44 <col style="width: 150px">
45 <col style="width: 280px">
46 <col style="width: 330px">
47 <col style="width: 120px">
48 </colgroup>
49 <thead>
50 <tr>
51 <th>参数名</th>
52 <th>输入/输出</th>
53 <th>描述</th>
54 <th>数据类型</th>
55 <th>数据格式</th>
56 </tr></thead>
57 <tbody>
58 <tr>
59 <td>self</td>
60 <td>输入</td>
61 <td>功能示例中的self,即待被在指定位置的值用value替换的张量。</td>
62 <td>FLOAT16、FLOAT、INT32、INT64、BOOL、BFLOAT16</td>
63 <td>ND</td>
64 </tr>
65 <tr>
66 <td>dim</td>
67 <td>输入</td>
68 <td>指定了self将要填充的维度。当self为1-8维时,dim的取值范围在[-self.dim(), self.dim()),当self为0维时,dim的取值范围在[-1, 1)。</td>
69 <td>int64</td>
70 <td>-</td>
71 </tr>
72 <tr>
73 <td>index</td>
74 <td>输入</td>
75 <td>指定self在dim维度将要填充的下标。其中的元素值小于self对应dim的维度大小。</td>
76 <td>-</td>
77 <td>-</td>
78 </tr>
79 <tr>
80 <td>value</td>
81 <td>输入</td>
82 <td>指定填充的数据值。需要可转化为self的数据类型。</td>
83 <td>与self一致</td>
84 <td>-</td>
85 </tr>
86 <tr>
87 <td>out</td>
88 <td>输出</td>
89 <td>指定的输出张量。</td>
90 <td>与self一致</td>
91 <td>ND</td>
92 </tr>
93 </tbody></table>
94 
95## 约束说明
96 
97
98## 调用说明
99 
100| 调用方式 | 调用样例 | 说明 |
101|--------------|------------------------------------------------------------------------|--------------------------------------------------------------|
102| aclnn调用 | [test_aclnn_index_fill_tensor](./examples/test_aclnn_index_fill_tensor.cpp) | 通过[aclnnIndexFillTensor](./docs/aclnnIndexFillTensor&aclnnInplaceIndexFillTensor.md)接口方式调用IndexFillD算子。 |
Mindex/index_fill_d/docs/aclnnIndexFill&aclnnInplaceIndexFill.md+4-1
@@ -1,9 +1,12 @@
1# aclnnIndexFill&aclnnInplaceIndexFill1# aclnnIndexFill&aclnnInplaceIndexFill
2 2 
3[📄 查看源码](https://gitcode.com/cann/ops-nn/tree/master/index/index_fill_d)
4 
3## 产品支持情况5## 产品支持情况
4 6 
5| 产品 | 是否支持 |7| 产品 | 是否支持 |
6| :----------------------------------------------------------- | :------: |8| :----------------------------------------------------------- | :------: |
9| Ascend 950PR/Ascend 950DT</term> | × |
7| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |10| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |
8| <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term> | √ |11| <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term> | √ |
9 12 
@@ -711,4 +714,4 @@ int main() {
711 aclFinalize();714 aclFinalize();
712 return 0;715 return 0;
713}716}
714```717```
Mindex/index_fill_d/docs/aclnnIndexFillTensor&aclnnInplaceIndexFillTensor.md+3-1
@@ -4,6 +4,7 @@
4 4 
5| 产品 | 是否支持 |5| 产品 | 是否支持 |
6| :----------------------------------------------------------- | :------: |6| :----------------------------------------------------------- | :------: |
7| Ascend 950PR/Ascend 950DT</term> | √ |
7| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |8| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |
8| <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term> | √ |9| <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term> | √ |
9 10 
@@ -352,7 +353,7 @@ aclnnStatus aclnnInplaceIndexFillTensor(
352 <td>-</td>353 <td>-</td>
353 </tr>354 </tr>
354 </tbody></table>355 </tbody></table>
355 356
356- **返回值**357- **返回值**
357 358 
358 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。359 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
@@ -438,6 +439,7 @@ aclnnStatus aclnnInplaceIndexFillTensor(
438- 确定性计算:439- 确定性计算:
439 - aclnnIndexFillTensor&aclnnInplaceIndexFillTensor默认确定性实现。440 - aclnnIndexFillTensor&aclnnInplaceIndexFillTensor默认确定性实现。
440 441 
442 
441## 调用示例443## 调用示例
442 444 
443示例代码如下,仅供参考,具体编译和执行过程请参考[编译与运行样例](../../../docs/zh/context/编译与运行样例.md)。445示例代码如下,仅供参考,具体编译和执行过程请参考[编译与运行样例](../../../docs/zh/context/编译与运行样例.md)。
Mindex/index_fill_d/examples/test_aclnn_index_fill.cpp+22-18
@@ -1,16 +1,17 @@
1/**1/**
2 * Copyright (c) 2025 Huawei Technologies Co., Ltd.2 * Copyright (c) 2025 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.
6 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8 * See LICENSE in the root of the software repository for the full text of the License.
9*/9 */
10
10#include <iostream>11#include <iostream>
11#include <vector>12#include <vector>
12#include "acl/acl.h"13#include "acl/acl.h"
13#include "aclnn_index_fill_tensor.h"14#include "aclnnop/aclnn_index_fill.h"
14 15 
15#define CHECK_RET(cond, return_expr) \16#define CHECK_RET(cond, return_expr) \
16 do { \17 do { \
@@ -67,7 +68,7 @@ int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>&
67}68}
68 69 
69int main() {70int main() {
70 // 1. (固定写法)device/stream初始化,参考acl对外接口列表71 // 1. (固定写法)device/stream初始化,参考acl API手册
71 // 根据自己的实际device填写deviceId72 // 根据自己的实际device填写deviceId
72 int32_t deviceId = 0;73 int32_t deviceId = 0;
73 aclrtStream stream;74 aclrtStream stream;
@@ -75,46 +76,48 @@ int main() {
75 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);76 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);
76 // 2. 构造输入与输出,需要根据API的接口自定义构造77 // 2. 构造输入与输出,需要根据API的接口自定义构造
77 std::vector<int64_t> selfShape = {3, 3};78 std::vector<int64_t> selfShape = {3, 3};
79 std::vector<int64_t> indexShape = {1};
78 std::vector<int64_t> outShape = selfShape;80 std::vector<int64_t> outShape = selfShape;
79 void* selfDeviceAddr = nullptr;81 void* selfDeviceAddr = nullptr;
80 void* outDeviceAddr = nullptr; 82 void* indexDeviceAddr = nullptr;
83 void* outDeviceAddr = nullptr;
81 aclTensor* self = nullptr;84 aclTensor* self = nullptr;
85 aclTensor* index = nullptr;
82 aclScalar* value = nullptr;86 aclScalar* value = nullptr;
83 aclIntArray* index = nullptr;
84 aclTensor* out = nullptr;87 aclTensor* out = nullptr;
85 std::vector<float> selfHostData = {0, 1, 2, 3, 4, 5, 6, 7, 8};88 std::vector<float> selfHostData = {0, 1, 2, 3, 4, 5, 6, 7, 8};
89 std::vector<int> indexHostData = {0};
86 std::vector<float> outHostData = {0, 0, 0, 0, 0, 0, 0, 0, 0};90 std::vector<float> outHostData = {0, 0, 0, 0, 0, 0, 0, 0, 0};
87 int64_t dim = 1;91 int64_t dim = 1;
88 float fillVal = 10;92 float fillVal = 10;
89 int64_t indexVal = 0;
90 // 创建self aclTensor93 // 创建self aclTensor
91 ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self);94 ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self);
92 CHECK_RET(ret == ACL_SUCCESS, return ret);95 CHECK_RET(ret == ACL_SUCCESS, return ret);
96 // 创建index aclTensor
97 ret = CreateAclTensor(indexHostData, indexShape, &indexDeviceAddr, aclDataType::ACL_INT64, &index);
98 CHECK_RET(ret == ACL_SUCCESS, return ret);
93 // 创建out aclTensor99 // 创建out aclTensor
94 ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out);100 ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out);
95 CHECK_RET(ret == ACL_SUCCESS, return ret);101 CHECK_RET(ret == ACL_SUCCESS, return ret);
96 // 创建value aclScalar102 // 创建value aclScalar
97 value = aclCreateScalar(&fillVal, aclDataType::ACL_FLOAT);103 value = aclCreateScalar(&fillVal, aclDataType::ACL_FLOAT);
98 CHECK_RET(value != nullptr, return ret);104 CHECK_RET(value != nullptr, return ret);
99 // 创建index aclIntArray
100 index = aclCreateIntArray(&indexVal, 1);
101 CHECK_RET(index != nullptr, return ret);
102 105 
103 // 3. 调用CANN算子库API,需要修改为具体的Api名称106 // 3. 调用CANN算子库API,需要修改为具体的Api名称
104 uint64_t workspaceSize = 0;107 uint64_t workspaceSize = 0;
105 aclOpExecutor* executor;108 aclOpExecutor* executor;
106 // 调用aclnnIndexFillTensor第一段接口109 // 调用aclnnIndexFill第一段接口
107 ret = aclnnIndexFillTensorGetWorkspaceSize(self, dim, index, value, out, &workspaceSize, &executor);110 ret = aclnnIndexFillGetWorkspaceSize(self, dim, index, value, out, &workspaceSize, &executor);
108 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnIndexFillTensorGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);111 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnIndexFillGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);
109 // 根据第一段接口计算出的workspaceSize申请device内存112 // 根据第一段接口计算出的workspaceSize申请device内存
110 void* workspaceAddr = nullptr;113 void* workspaceAddr = nullptr;
111 if (workspaceSize > 0) {114 if (workspaceSize > 0) {
112 ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);115 ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
113 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);116 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
114 }117 }
115 // 调用aclnnIndexFillTensor第二段接口118 // 调用aclnnIndexFill第二段接口
116 ret = aclnnIndexFillTensor(workspaceAddr, workspaceSize, executor, stream);119 ret = aclnnIndexFill(workspaceAddr, workspaceSize, executor, stream);
117 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnIndexFillTensor failed. ERROR: %d\n", ret); return ret);120 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnIndexFill failed. ERROR: %d\n", ret); return ret);
118 // 4. (固定写法)同步等待任务执行结束121 // 4. (固定写法)同步等待任务执行结束
119 ret = aclrtSynchronizeStream(stream);122 ret = aclrtSynchronizeStream(stream);
120 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);123 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
@@ -130,12 +133,13 @@ int main() {
130 133 
131 // 6. 释放申请的变量,需要根据具体API的接口定义修改134 // 6. 释放申请的变量,需要根据具体API的接口定义修改
132 aclDestroyTensor(self);135 aclDestroyTensor(self);
136 aclDestroyTensor(index);
133 aclDestroyTensor(out);137 aclDestroyTensor(out);
134 aclDestroyScalar(value);138 aclDestroyScalar(value);
135 aclDestroyIntArray(index);
136 139 
137 // 7. 释放device资源,需要根据具体API的接口定义修改140 // 7. 释放device资源,需要根据具体API的接口定义修改
138 aclrtFree(selfDeviceAddr);141 aclrtFree(selfDeviceAddr);
142 aclrtFree(indexDeviceAddr);
139 aclrtFree(outDeviceAddr);143 aclrtFree(outDeviceAddr);
140 if (workspaceSize > 0) {144 if (workspaceSize > 0) {
141 aclrtFree(workspaceAddr);145 aclrtFree(workspaceAddr);
Dindex/index_fill_d/examples/test_aclnn_index_fill_d.cpp+0-150
@@ -1,150 +0,0 @@
1/**
2 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.
6 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 * See LICENSE in the root of the software repository for the full text of the License.
9 */
10#include <iostream>
11#include <vector>
12#include "acl/acl.h"
13#include "aclnnop/aclnn_index_fill.h"
14 
15#define CHECK_RET(cond, return_expr) \
16 do { \
17 if (!(cond)) { \
18 return_expr; \
19 } \
20 } while (0)
21 
22#define LOG_PRINT(message, ...) \
23 do { \
24 printf(message, ##__VA_ARGS__); \
25 } while (0)
26 
27int64_t GetShapeSize(const std::vector<int64_t>& shape) {
28 int64_t shapeSize = 1;
29 for (auto i : shape) {
30 shapeSize *= i;
31 }
32 return shapeSize;
33}
34 
35int Init(int32_t deviceId, aclrtStream* stream) {
36 // 固定写法,资源初始化
37 auto ret = aclInit(nullptr);
38 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);
39 ret = aclrtSetDevice(deviceId);
40 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);
41 ret = aclrtCreateStream(stream);
42 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);
43 return 0;
44}
45 
46template <typename T>
47int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr,
48 aclDataType dataType, aclTensor** tensor) {
49 auto size = GetShapeSize(shape) * sizeof(T);
50 // 调用aclrtMalloc申请device侧内存
51 auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);
52 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);
53 // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上
54 ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);
55 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);
56 
57 // 计算连续tensor的strides
58 std::vector<int64_t> strides(shape.size(), 1);
59 for (int64_t i = shape.size() - 2; i >= 0; i--) {
60 strides[i] = shape[i + 1] * strides[i + 1];
61 }
62 
63 // 调用aclCreateTensor接口创建aclTensor
64 *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND,
65 shape.data(), shape.size(), *deviceAddr);
66 return 0;
67}
68 
69int main() {
70 // 1. (固定写法)device/stream初始化,参考acl API手册
71 // 根据自己的实际device填写deviceId
72 int32_t deviceId = 0;
73 aclrtStream stream;
74 auto ret = Init(deviceId, &stream);
75 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);
76 // 2. 构造输入与输出,需要根据API的接口自定义构造
77 std::vector<int64_t> selfShape = {3, 3};
78 std::vector<int64_t> indexShape = {1};
79 std::vector<int64_t> outShape = selfShape;
80 void* selfDeviceAddr = nullptr;
81 void* indexDeviceAddr = nullptr;
82 void* outDeviceAddr = nullptr;
83 aclTensor* self = nullptr;
84 aclTensor* index = nullptr;
85 aclScalar* value = nullptr;
86 aclTensor* out = nullptr;
87 std::vector<float> selfHostData = {0, 1, 2, 3, 4, 5, 6, 7, 8};
88 std::vector<int> indexHostData = {0};
89 std::vector<float> outHostData = {0, 0, 0, 0, 0, 0, 0, 0, 0};
90 int64_t dim = 1;
91 float fillVal = 10;
92 // 创建self aclTensor
93 ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self);
94 CHECK_RET(ret == ACL_SUCCESS, return ret);
95 // 创建index aclTensor
96 ret = CreateAclTensor(indexHostData, indexShape, &indexDeviceAddr, aclDataType::ACL_INT64, &index);
97 CHECK_RET(ret == ACL_SUCCESS, return ret);
98 // 创建out aclTensor
99 ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out);
100 CHECK_RET(ret == ACL_SUCCESS, return ret);
101 // 创建value aclScalar
102 value = aclCreateScalar(&fillVal, aclDataType::ACL_FLOAT);
103 CHECK_RET(value != nullptr, return ret);
104 
105 // 3. 调用CANN算子库API,需要修改为具体的Api名称
106 uint64_t workspaceSize = 0;
107 aclOpExecutor* executor;
108 // 调用aclnnIndexFill第一段接口
109 ret = aclnnIndexFillGetWorkspaceSize(self, dim, index, value, out, &workspaceSize, &executor);
110 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnIndexFillGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);
111 // 根据第一段接口计算出的workspaceSize申请device内存
112 void* workspaceAddr = nullptr;
113 if (workspaceSize > 0) {
114 ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
115 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
116 }
117 // 调用aclnnIndexFill第二段接口
118 ret = aclnnIndexFill(workspaceAddr, workspaceSize, executor, stream);
119 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnIndexFill failed. ERROR: %d\n", ret); return ret);
120 // 4. (固定写法)同步等待任务执行结束
121 ret = aclrtSynchronizeStream(stream);
122 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
123 // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改
124 auto size = GetShapeSize(outShape);
125 std::vector<float> resultData(size, 0);
126 ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr,
127 size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST);
128 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
129 for (int64_t i = 0; i < size; i++) {
130 LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]);
131 }
132 
133 // 6. 释放申请的变量,需要根据具体API的接口定义修改
134 aclDestroyTensor(self);
135 aclDestroyTensor(index);
136 aclDestroyTensor(out);
137 aclDestroyScalar(value);
138 
139 // 7. 释放device资源,需要根据具体API的接口定义修改
140 aclrtFree(selfDeviceAddr);
141 aclrtFree(indexDeviceAddr);
142 aclrtFree(outDeviceAddr);
143 if (workspaceSize > 0) {
144 aclrtFree(workspaceAddr);
145 }
146 aclrtDestroyStream(stream);
147 aclrtResetDevice(deviceId);
148 aclFinalize();
149 return 0;
150}
Mindex/index_fill_d/examples/test_aclnn_index_fill_tensor.cpp+5-4
@@ -1,16 +1,17 @@
1/**1/**
2 * Copyright (c) 2025 Huawei Technologies Co., Ltd.2 * Copyright (c) 2025 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.
6 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8 * See LICENSE in the root of the software repository for the full text of the License.
9*/9 */
10
10#include <iostream>11#include <iostream>
11#include <vector>12#include <vector>
12#include "acl/acl.h"13#include "acl/acl.h"
13#include "aclnn_index_fill_tensor.h"14#include "aclnnop/aclnn_index_fill_tensor.h"
14 15 
15#define CHECK_RET(cond, return_expr) \16#define CHECK_RET(cond, return_expr) \
16 do { \17 do { \
Mindex/index_fill_d/examples/test_aclnn_inplace_index_fill.cpp+22-27
@@ -1,16 +1,17 @@
1/**1/**
2 * Copyright (c) 2025 Huawei Technologies Co., Ltd.2 * Copyright (c) 2025 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.
6 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8 * See LICENSE in the root of the software repository for the full text of the License.
9*/9 */
10
10#include <iostream>11#include <iostream>
11#include <vector>12#include <vector>
12#include "acl/acl.h"13#include "acl/acl.h"
13#include "aclnn_index_fill_tensor.h"14#include "aclnnop/aclnn_index_fill.h"
14 15 
15#define CHECK_RET(cond, return_expr) \16#define CHECK_RET(cond, return_expr) \
16 do { \17 do { \
@@ -67,7 +68,7 @@ int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>&
67}68}
68 69 
69int main() {70int main() {
70 // 1. (固定写法)device/stream初始化,参考acl对外接口列表71 // 1. (固定写法)device/stream初始化,参考acl API手册
71 // 根据自己的实际device填写deviceId72 // 根据自己的实际device填写deviceId
72 int32_t deviceId = 0;73 int32_t deviceId = 0;
73 aclrtStream stream;74 aclrtStream stream;
@@ -75,53 +76,48 @@ int main() {
75 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);76 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);
76 // 2. 构造输入与输出,需要根据API的接口自定义构造77 // 2. 构造输入与输出,需要根据API的接口自定义构造
77 std::vector<int64_t> selfShape = {3, 3};78 std::vector<int64_t> selfShape = {3, 3};
78 std::vector<int64_t> outShape = selfShape;79 std::vector<int64_t> indexShape = {1};
79 void* selfDeviceAddr = nullptr;80 void* selfDeviceAddr = nullptr;
80 void* outDeviceAddr = nullptr; 81 void* indexDeviceAddr = nullptr;
81 aclTensor* self = nullptr;82 aclTensor* self = nullptr;
83 aclTensor* index = nullptr;
82 aclScalar* value = nullptr;84 aclScalar* value = nullptr;
83 aclIntArray* index = nullptr;
84 aclTensor* out = nullptr;
85 std::vector<float> selfHostData = {0, 1, 2, 3, 4, 5, 6, 7, 8};85 std::vector<float> selfHostData = {0, 1, 2, 3, 4, 5, 6, 7, 8};
86 std::vector<float> outHostData = {0, 0, 0, 0, 0, 0, 0, 0, 0};86 std::vector<int> indexHostData = {0};
87 int64_t dim = 1;87 int64_t dim = 1;
88 float fillVal = 10;88 float fillVal = 10;
89 int64_t indexVal = 0;
90 // 创建self aclTensor89 // 创建self aclTensor
91 ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self);90 ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self);
92 CHECK_RET(ret == ACL_SUCCESS, return ret);91 CHECK_RET(ret == ACL_SUCCESS, return ret);
93 // 创建out aclTensor92 // 创建index aclTensor
94 ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out);93 ret = CreateAclTensor(indexHostData, indexShape, &indexDeviceAddr, aclDataType::ACL_INT64, &index);
95 CHECK_RET(ret == ACL_SUCCESS, return ret);94 CHECK_RET(ret == ACL_SUCCESS, return ret);
96 // 创建value aclScalar95 // 创建value aclScalar
97 value = aclCreateScalar(&fillVal, aclDataType::ACL_FLOAT);96 value = aclCreateScalar(&fillVal, aclDataType::ACL_FLOAT);
98 CHECK_RET(value != nullptr, return ret);97 CHECK_RET(value != nullptr, return ret);
99 // 创建index aclIntArray
100 index = aclCreateIntArray(&indexVal, 1);
101 CHECK_RET(index != nullptr, return ret);
102 98 
103 // 3. 调用CANN算子库API,需要修改为具体的Api名称99 // 3. 调用CANN算子库API,需要修改为具体的Api名称
104 uint64_t workspaceSize = 0;100 uint64_t workspaceSize = 0;
105 aclOpExecutor* executor;101 aclOpExecutor* executor;
106 // 调用aclnnIndexFillTensor第一段接口102 // 调用aclnnInplaceIndexFill第一段接口
107 ret = aclnnIndexFillTensorGetWorkspaceSize(self, dim, index, value, out, &workspaceSize, &executor);103 ret = aclnnInplaceIndexFillGetWorkspaceSize(self, dim, index, value, &workspaceSize, &executor);
108 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnIndexFillTensorGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);104 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnIndexFillGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);
109 // 根据第一段接口计算出的workspaceSize申请device内存105 // 根据第一段接口计算出的workspaceSize申请device内存
110 void* workspaceAddr = nullptr;106 void* workspaceAddr = nullptr;
111 if (workspaceSize > 0) {107 if (workspaceSize > 0) {
112 ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);108 ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
113 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);109 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
114 }110 }
115 // 调用aclnnIndexFillTensor第二段接口111 // 调用aclnnInplaceIndexFill第二段接口
116 ret = aclnnIndexFillTensor(workspaceAddr, workspaceSize, executor, stream);112 ret = aclnnInplaceIndexFill(workspaceAddr, workspaceSize, executor, stream);
117 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnIndexFillTensor failed. ERROR: %d\n", ret); return ret);113 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnInplaceIndexFill failed. ERROR: %d\n", ret); return ret);
118 // 4. (固定写法)同步等待任务执行结束114 // 4. (固定写法)同步等待任务执行结束
119 ret = aclrtSynchronizeStream(stream);115 ret = aclrtSynchronizeStream(stream);
120 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);116 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
121 // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改117 // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改
122 auto size = GetShapeSize(outShape);118 auto size = GetShapeSize(selfShape);
123 std::vector<float> resultData(size, 0);119 std::vector<float> resultData(size, 0);
124 ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr,120 ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), selfDeviceAddr,
125 size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST);121 size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST);
126 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);122 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
127 for (int64_t i = 0; i < size; i++) {123 for (int64_t i = 0; i < size; i++) {
@@ -130,13 +126,12 @@ int main() {
130 126 
131 // 6. 释放申请的变量,需要根据具体API的接口定义修改127 // 6. 释放申请的变量,需要根据具体API的接口定义修改
132 aclDestroyTensor(self);128 aclDestroyTensor(self);
133 aclDestroyTensor(out);129 aclDestroyTensor(index);
134 aclDestroyScalar(value);130 aclDestroyScalar(value);
135 aclDestroyIntArray(index);
136 131 
137 // 7. 释放device资源,需要根据具体API的接口定义修改132 // 7. 释放device资源,需要根据具体API的接口定义修改
138 aclrtFree(selfDeviceAddr);133 aclrtFree(selfDeviceAddr);
139 aclrtFree(outDeviceAddr);134 aclrtFree(indexDeviceAddr);
140 if (workspaceSize > 0) {135 if (workspaceSize > 0) {
141 aclrtFree(workspaceAddr);136 aclrtFree(workspaceAddr);
142 }137 }
Mindex/index_fill_d/examples/test_aclnn_inplace_index_fill_tensor.cpp+10-16
@@ -1,23 +1,17 @@
1/**1/**
2* Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.2 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3*3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4* Licensed under the Apache License, Version 2.0 (the "License");4 * CANN Open Software License Agreement Version 2.0 (the "License").
5* 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.
6* You may obtain a copy of the License at6 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7*7 * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8* http://www.apache.org/licenses/LICENSE-2.08 * See LICENSE in the root of the software repository for the full text of the License.
9*9 */
10* Unless required by applicable law or agreed to in writing, software10
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16 
17#include <iostream>11#include <iostream>
18#include <vector>12#include <vector>
19#include "acl/acl.h"13#include "acl/acl.h"
20#include "aclnn_index_fill_tensor.h"14#include "aclnnop/aclnn_index_fill_tensor.h"
21 15 
22#define CHECK_RET(cond, return_expr) \16#define CHECK_RET(cond, return_expr) \
23 do { \17 do { \
Rindex/index_fill_d/op_host/op_api/aclnn_index_fill.cppindex/index_fill_d/op_api/aclnn_index_fill.cpp+0-0
文件重命名但无更改。
Aindex/index_fill_d/op_api/aclnn_index_fill.h+53-0
@@ -0,0 +1,53 @@
1/**
2 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.
6 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 * See LICENSE in the root of the software repository for the full text of the License.
9 */
10 
11#ifndef OP_API_INC_LEVEL2_ACLNN_INDEX_FILL_H_
12#define OP_API_INC_LEVEL2_ACLNN_INDEX_FILL_H_
13 
14#include "aclnn/aclnn_base.h"
15#include "aclnn_util.h"
16 
17#ifdef __cplusplus
18extern "C" {
19#endif
20 
21/**
22 * @brief aclnnIndexFill的第一段接口,根据具体的计算流程,计算workspace大小。
23 * @domain aclnn_ops_infer
24 */
25ACLNN_API aclnnStatus aclnnIndexFillGetWorkspaceSize(
26 const aclTensor* self, int64_t dim, const aclTensor* index, const aclScalar* value, aclTensor* out,
27 uint64_t* workspaceSize, aclOpExecutor** executor);
28 
29/**
30 * @brief aclnnIndexFill的第二段接口,用于执行计算。
31 */
32ACLNN_API aclnnStatus
33aclnnIndexFill(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream);
34 
35/**
36 * @brief aclnnInplaceIndexFill的第一段接口,根据具体的计算流程,计算workspace大小。
37 * @domain aclnn_ops_infer
38 */
39ACLNN_API aclnnStatus aclnnInplaceIndexFillGetWorkspaceSize(
40 aclTensor* selfRef, int64_t dim, const aclTensor* index, const aclScalar* value, uint64_t* workspaceSize,
41 aclOpExecutor** executor);
42 
43/**
44 * @brief aclnnInplaceIndexFill的第二段接口,用于执行计算。
45 */
46ACLNN_API aclnnStatus
47aclnnInplaceIndexFill(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream);
48 
49#ifdef __cplusplus
50}
51#endif
52 
53#endif // OP_API_INC_LEVEL2_ACLNN_INDEX_FILL_H_
Rindex/index_fill_d/op_host/op_api/aclnn_index_fill_tensor.cppindex/index_fill_d/op_api/aclnn_index_fill_tensor.cpp+0-0
文件重命名但无更改。
Aindex/index_fill_d/op_api/aclnn_index_fill_tensor.h+52-0
@@ -0,0 +1,52 @@
1/**
2 * Copyright (c) 2025 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#ifndef OP_API_INC_LEVEL2_ACLNN_INDEX_FILL_TENSOR_H_
11#define OP_API_INC_LEVEL2_ACLNN_INDEX_FILL_TENSOR_H_
12 
13#include "aclnn/aclnn_base.h"
14#include "aclnn_util.h"
15 
16#ifdef __cplusplus
17extern "C" {
18#endif
19 
20/**
21 * @brief aclnnIndexFillTensor的第一段接口,根据具体的计算流程,计算workspace大小。
22 * @domain aclnn_ops_infer
23 */
24ACLNN_API aclnnStatus aclnnIndexFillTensorGetWorkspaceSize(const aclTensor* self, int64_t dim, const aclIntArray* index,
25 const aclScalar* value, aclTensor* out,
26 uint64_t* workspaceSize, aclOpExecutor** executor);
27 
28/**
29 * @brief aclnnIndexFillTensor的第二段接口,用于执行计算。
30 */
31ACLNN_API aclnnStatus aclnnIndexFillTensor(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor,
CANN-robot
CANN-robotCANN-robot2025年12月28日

指针与引用安全: 函数aclnnIndexFillTensor的workspace参数为void*类型,但未在接口中明确说明当workspaceSize为0时workspace是否允许为NULL。类似地,executor指针也未标注是否必须非空。这可能导致调用方在实现时产生歧义。

问题类型: 指针与引用安全 文件路径: index/index_fill_d/op_api/aclnn_index_fill_tensor.h 行号: 31 问题代码:

ACLNN_API aclnnStatus aclnnIndexFillTensor(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor,
                                           aclrtStream stream);

修改建议:

在函数注释中明确说明:当workspaceSize为0时workspace可为NULL;executor必须为非空(因来自GetWorkspaceSize的输出)。同时建议检查stream参数是否允许为默认流(如NULL或0),若允许也需说明。

此评论由代码审查工具自动生成

likedislike
32 aclrtStream stream);
33 
34/**
35 * @brief aclnnInplaceIndexFillTensor的第一段接口,根据具体的计算流程,计算workspace大小。
36 * @domain aclnn_ops_infer
37 */
38ACLNN_API aclnnStatus aclnnInplaceIndexFillTensorGetWorkspaceSize(aclTensor* selfRef, int64_t dim,
CANN-robot
CANN-robotCANN-robot2025年12月28日

代码结构与可维护性: 函数aclnnInplaceIndexFillTensorGetWorkspaceSize的参数selfRef类型为aclTensor*(非const),而aclnnIndexFillTensorGetWorkspaceSize的对应参数self为const aclTensor*。这种不一致性可能反映设计意图(原地修改需非const),但未在文档中说明,容易引起困惑。

问题类型: 代码结构与可维护性 文件路径: index/index_fill_d/op_api/aclnn_index_fill_tensor.h 行号: 38 问题代码:

ACLNN_API aclnnStatus aclnnInplaceIndexFillTensorGetWorkspaceSize(aclTensor* selfRef, int64_t dim,
                                                                  const aclIntArray* index, const aclScalar* value,
                                                                  uint64_t* workspaceSize, aclOpExecutor** executor);

修改建议:

在函数注释中明确说明selfRef为输入输出参数(原地修改),并解释为何此处为非const指针。同时检查整个接口设计中const使用的一致性,确保同类参数(如index、value)在两组函数中保持相同的const修饰。

此评论由代码审查工具自动生成

likedislike
39 const aclIntArray* index, const aclScalar* value,
40 uint64_t* workspaceSize, aclOpExecutor** executor);
41 
42/**
43 * @brief aclnnInplaceIndexFillTensor的第二段接口,用于执行计算。
44 */
45ACLNN_API aclnnStatus aclnnInplaceIndexFillTensor(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor,
46 aclrtStream stream);
47 
48#ifdef __cplusplus
49}
50#endif
51 
52#endif // OP_API_INC_LEVEL2_ACLNN_INDEX_FILL_TENSOR_H_
Rindex/index_fill_d/op_host/op_api/index_fill.cppindex/index_fill_d/op_api/index_fill.cpp+0-0
文件重命名但无更改。
Aindex/index_fill_d/op_api/index_fill.h+28-0
@@ -0,0 +1,28 @@
1/**
2 * Copyright (c) 2025 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 index_fill.h
13 * \brief
14 */
15 
16#ifndef PTA_NPU_OP_API_INC_LEVEL0_OP_INDEXFILL_OP_H_
17#define PTA_NPU_OP_API_INC_LEVEL0_OP_INDEXFILL_OP_H_
18 
19#include "opdev/op_executor.h"
20namespace l0op {
21const aclTensor *IndexFillD(const aclTensor *self, const aclTensor *assist1, const aclTensor *assist2,
22 int64_t dim, aclOpExecutor *executor);
23 
24const aclTensor *IndexFill(const aclTensor *self, const aclTensor *indices, const aclTensor *value,
25 int64_t dim, aclOpExecutor *executor);
26}
27 
28#endif // PTA_NPU_OP_API_INC_LEVEL0_OP_INDEXFILL_OP_H_
Aindex/index_fill_d/op_graph/index_fill_d_proto.h+48-0
@@ -0,0 +1,48 @@
1/**
2 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.
6 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 * See LICENSE in the root of the software repository for the full text of the License.
9 */
10 
11#ifndef OPS_BUILT_IN_OP_PROTO_INC_SELECTION_OPS_H_
12#define OPS_BUILT_IN_OP_PROTO_INC_SELECTION_OPS_H_
13#include "graph/operator_reg.h"
14 
15namespace ge {
16/**
17* @brief Fills the elements of the input tensor with value val by selecting the indices in the order given in index.
18 
19* @par Inputs:
20* Three inputs, including:
21* @li x: A tensor. Must be one of the following types:
22* float16, float32, int32, bfloat16. \n
23* @li assist1: A tensor. Must be one of the following types:
24* float16, float32, int32, bfloat16. \n
25* @li assist2: A tensor. Must be one of the following types:
26* float16, float32, int32, bfloat16. \n
27 
28* @par Attributes:
29* dim: A required int. Used to select the dimension of this tensor. \n
30 
31* @par Outputs:
32* y: A tensor with the same type and shape as 'x'. \n
33 
34* @par Third-party framework compatibility
35* Compatible with the Pytorch operator IndexFill. \n
36 
37* @attention Constraints:
38* The operator will not be enhanced in the future.
39*/
40REG_OP(IndexFillD)
41 .INPUT(x, TensorType({DT_FLOAT16, DT_FLOAT, DT_INT32, DT_BF16}))
42 .INPUT(assist1, TensorType({DT_FLOAT16, DT_FLOAT, DT_INT32, DT_BF16}))
43 .INPUT(assist2, TensorType({DT_FLOAT16, DT_FLOAT, DT_INT32, DT_BF16}))
44 .OUTPUT(y, TensorType({DT_FLOAT16, DT_FLOAT, DT_INT32, DT_BF16}))
45 .REQUIRED_ATTR(dim, Int)
46 .OP_END_FACTORY_REG(IndexFillD)
47} // namespace ge
48#endif
Aindex/index_fill_d/op_host/arch35/index_fill_d_tiling.cpp+200-0
@@ -0,0 +1,200 @@
1/**
2 * Copyright (c) 2025 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 index_fill_d_tiling.cc
13 * \brief
14 */
15#include "index_fill_d_tiling.h"
16#include "log/log.h"
17#include "op_host/util/math_util.h"
18#include "atvoss/elewise/elewise_tiling.h"
19#include "tiling/platform/platform_ascendc.h"
20 
21namespace optiling
22{
23using namespace Ops::Base;
24const int64_t BUFFER_NUM = 2;
25const int64_t ALL_BUFFERS = 4;
26const int64_t INPUT_X_IDX = 0;
27const int64_t INPUT_ASSIST1_IDX = 1;
28const int64_t INPUT_ASSIST2_IDX = 2;
29const int64_t OUTPUT_Y_IDX = 0;
30const int64_t MIN_DATA_SIZE = 1024;
31const int64_t ASCEND_WORKSPACE = 16 * 1024 * 1024;
32const uint64_t TILING_KEY_COMMON = 200;
33const uint64_t ALIGN_SIZE = 512;
34 
35static const std::set<ge::DataType> SUPPORT_DTYPE = {
36 ge::DT_FLOAT, ge::DT_FLOAT16, ge::DT_INT32, ge::DT_INT64,ge::DT_BOOL, ge::DT_BF16
37};
38 
39ge::graphStatus IndexFillDTiling::CheckShape()
40{
41 auto xShapePtr = context_->GetRequiredInputShape(INPUT_X_IDX);
42 OP_CHECK_NULL_WITH_CONTEXT(context_, xShapePtr);
43 auto xShape = xShapePtr->GetStorageShape();
44 
45 auto assist1ShapePtr = context_->GetRequiredInputShape(INPUT_ASSIST1_IDX);
46 OP_CHECK_NULL_WITH_CONTEXT(context_, assist1ShapePtr);
47 auto assist1Shape = assist1ShapePtr->GetStorageShape();
48 
49 auto assist2ShapePtr = context_->GetRequiredInputShape(INPUT_ASSIST2_IDX);
50 OP_CHECK_NULL_WITH_CONTEXT(context_, assist2ShapePtr);
51 auto assist2Shape = assist2ShapePtr->GetStorageShape();
52 
53 auto yShapePtr = context_->GetOutputShape(OUTPUT_Y_IDX);
54 OP_CHECK_NULL_WITH_CONTEXT(context_, yShapePtr);
55 auto yShape = yShapePtr->GetStorageShape();
56 
57 OP_CHECK_IF(xShape != assist1Shape || xShape != assist2Shape || xShape != yShape,
58 OP_LOGE(context_->GetNodeName(),
59 "input x, assist1, assist2 and y shape must be same, please check"),
60 return ge::GRAPH_FAILED);
61 inputXShape_ = xShape;
62 return ge::GRAPH_SUCCESS;
63}
64 
65inline static bool IsSupportDtype(const std::set<ge::DataType> &supportDtype, const ge::DataType dtype)
66{
67 return (supportDtype.count(dtype) != 0);
68}
69 
70ge::graphStatus IndexFillDTiling::CheckDataType()
71{
72 auto inputXPtr = context_->GetRequiredInputDesc(INPUT_X_IDX);
73 OP_CHECK_NULL_WITH_CONTEXT(context_, inputXPtr);
74 dType_ = inputXPtr->GetDataType();
75 auto assist1Ptr = context_->GetRequiredInputDesc(INPUT_ASSIST1_IDX);
76 OP_CHECK_NULL_WITH_CONTEXT(context_, assist1Ptr);
77 auto assist1DType = assist1Ptr->GetDataType();
78 auto assist2Ptr = context_->GetRequiredInputDesc(INPUT_ASSIST2_IDX);
79 OP_CHECK_NULL_WITH_CONTEXT(context_, assist2Ptr);
80 auto assist2DType = assist2Ptr->GetDataType();
81 auto outputPtr = context_->GetOutputDesc(OUTPUT_Y_IDX);
82 OP_CHECK_NULL_WITH_CONTEXT(context_, outputPtr);
83 auto outputDtype = outputPtr->GetDataType();
84 OP_CHECK_IF(!IsSupportDtype(SUPPORT_DTYPE, dType_), OP_LOGE(context_->GetNodeName(),
85 "The dtype only support float32, float16, int32, int64, bool, bfloat16 \
86 currently, please check."), return ge::GRAPH_FAILED);
87 OP_CHECK_IF(dType_ != assist1DType || dType_ != assist2DType || dType_ != outputDtype,
88 OP_LOGE(context_->GetNodeName(),
89 "input x, assist1, assist2 and y dtype must be same, please check"),
90 return ge::GRAPH_FAILED);
91 dataTypeSize_ = ge::GetSizeByDataType(dType_);
92 OP_CHECK_IF(dataTypeSize_ == -1, OP_LOGE(context_->GetNodeName(),
93 "Get the size of dtype failed, please check."), return ge::GRAPH_FAILED);
94 return ge::GRAPH_SUCCESS;
95}
96 
97bool IndexFillDTiling::IsCapable() {
98 return true;
99}
100 
101ge::graphStatus IndexFillDTiling::GetShapeAttrsInfo() {
102 if (CheckDataType() != ge::GRAPH_SUCCESS) {
103 return ge::GRAPH_FAILED;
104 }
105 
106 return CheckShape();
107}
108 
109ge::graphStatus IndexFillDTiling::GetPlatformInfo() {
110 auto compileInfo = reinterpret_cast<const IndexFillDCompileInfo *>(context_->GetCompileInfo());
111 OP_CHECK_NULL_WITH_CONTEXT(context_, compileInfo);
112 totalCoreNum_ = compileInfo->coreNum;
113 ubSize_ = compileInfo->ubSize;
114 return ge::GRAPH_SUCCESS;
115}
116 
117ge::graphStatus IndexFillDTiling::DoOpTiling() {
118 inputShapeSize_ = inputXShape_.GetShapeSize();
119 int64_t maxUbAvailable = ubSize_ / (BUFFER_NUM * ALL_BUFFERS * dataTypeSize_);
120 normalCoreData_ = std::max(CeilDiv(inputShapeSize_, totalCoreNum_), MIN_DATA_SIZE);
121 usedCoreNum_ = CeilDiv(inputShapeSize_, normalCoreData_);
122 tailCoreData_ = inputShapeSize_ - (usedCoreNum_ - 1) * normalCoreData_;
123 ubFactor_ = (maxUbAvailable / ALIGN_SIZE) * ALIGN_SIZE;
124 normalCoreLoop_ = (normalCoreData_ + ubFactor_ - 1) / ubFactor_;
125 tailUbFactor_ = normalCoreData_ - (normalCoreLoop_ - 1) * ubFactor_;
126 tailCoreLoop_ = (tailCoreData_ + ubFactor_ - 1) / ubFactor_;
127 tailCoreTailUbFactor_ = tailCoreData_ - (tailCoreLoop_ - 1) * ubFactor_;
128 return ge::GRAPH_SUCCESS;
129}
130 
131ge::graphStatus IndexFillDTiling::DoLibApiTiling() {
132 return ge::GRAPH_SUCCESS;
133}
134 
135uint64_t IndexFillDTiling::GetTilingKey() const {
136 return TILING_KEY_COMMON;
137}
138 
139ge::graphStatus IndexFillDTiling::GetWorkspaceSize() {
140 workspaceSize_ = ASCEND_WORKSPACE;
141 return ge::GRAPH_SUCCESS;
142}
143 
144ge::graphStatus IndexFillDTiling::PostTiling() {
145 tilingData_.set_normalCoreData(normalCoreData_);
146 tilingData_.set_tailCoreData(tailCoreData_);
147 tilingData_.set_ubFactor(ubFactor_);
148 tilingData_.set_tailUbFactor(tailUbFactor_);
149 tilingData_.set_tailCoreTailUbFactor(tailCoreTailUbFactor_);
150 tilingData_.set_normalCoreLoop(normalCoreLoop_);
151 tilingData_.set_tailCoreLoop(tailCoreLoop_);
152 auto workspaces = context_->GetWorkspaceSizes(1);
153 OP_CHECK_NULL_WITH_CONTEXT(context_, workspaces);
154 workspaces[0] = workspaceSize_;
155 context_->SetBlockDim(usedCoreNum_);
156 tilingData_.SaveToBuffer(context_->GetRawTilingData()->GetData(), context_->GetRawTilingData()->GetCapacity());
157 context_->GetRawTilingData()->SetDataSize(tilingData_.GetDataSize());
158 return ge::GRAPH_SUCCESS;
159}
160 
161void IndexFillDTiling::DumpTilingInfo() {
162 std::ostringstream info;
163 info << "usedCoreNum: " << usedCoreNum_;
164 info << ", normalCoreData: " << normalCoreData_;
165 info << ", tailCoreData: " << tailCoreData_;
166 info << ", ubFactor: " << ubFactor_;
167 info << ", tailUbFactor: " << tailUbFactor_;
168 info << ", tailCoreTailUbFactor: " << tailCoreTailUbFactor_;
169 info << ", normalCoreLoop: " << normalCoreLoop_;
170 info << ", tailCoreLoop: " << tailCoreLoop_;
171 info << ", tilingKey: " << GetTilingKey();
172 OP_LOGI(context_->GetNodeName(), "%s", info.str().c_str());
173}
174 
175static ge::graphStatus Tiling4IndexFillD(gert::TilingContext* tilingContextGen)
176{
177 OP_LOGD(tilingContextGen->GetNodeName(), "TilingIndexFillD rt2.0 is running.");
178 auto compileInfo = reinterpret_cast<const IndexFillDCompileInfo*>(tilingContextGen->GetCompileInfo());
179 OP_CHECK_NULL_WITH_CONTEXT(tilingContextGen, compileInfo);
180 IndexFillDTiling baseOpTiling(tilingContextGen);
181 return baseOpTiling.DoTiling();
182}
183 
184ge::graphStatus TilingPrepareForIndexFillD(gert::TilingParseContext* context)
185{
186 OP_LOGD(context->GetNodeName(), "TilingPrepareForIndexFillD is running.");
187 auto compileInfo = context->GetCompiledInfo<IndexFillDCompileInfo>();
188 OP_CHECK_NULL_WITH_CONTEXT(context, compileInfo);
189 auto platformInfo = context->GetPlatformInfo();
190 OP_CHECK_NULL_WITH_CONTEXT(context, platformInfo);
191 auto ascendcPlatform = platform_ascendc::PlatformAscendC(platformInfo);
192 compileInfo->coreNum = ascendcPlatform.GetCoreNumAiv();
193 uint64_t ubSize;
194 ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::UB, ubSize);
195 compileInfo->ubSize = static_cast<int64_t>(ubSize);
196 return ge::GRAPH_SUCCESS;
197}
198 
199IMPL_OP_OPTILING(IndexFillD).Tiling(Tiling4IndexFillD).TilingParse<IndexFillDCompileInfo>(TilingPrepareForIndexFillD);
200} // namespace optiling
Aindex/index_fill_d/op_host/arch35/index_fill_d_tiling.h+80-0
@@ -0,0 +1,80 @@
1/**
2 * Copyright (c) 2025 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 index_fill_d_tiling.h
13 * \brief
14 */
15#ifndef OPS_BUILD_IN_OP_TILING_RUNTIME_INDEX_FILL_D_TILING_H
16#define OPS_BUILD_IN_OP_TILING_RUNTIME_INDEX_FILL_D_TILING_H
17#include "register/op_def_registry.h"
18#include "tiling_base/tiling_base.h"
19#include "register/tilingdata_base.h"
20 
21namespace optiling {
22using namespace Ops::NN::Optiling;
23 
24BEGIN_TILING_DATA_DEF(IndexFillDTilingData)
25TILING_DATA_FIELD_DEF(int64_t, normalCoreData);
26TILING_DATA_FIELD_DEF(int64_t, tailCoreData);
27TILING_DATA_FIELD_DEF(int64_t, ubFactor);
28TILING_DATA_FIELD_DEF(int64_t, tailUbFactor);
29TILING_DATA_FIELD_DEF(int64_t, tailCoreTailUbFactor);
30TILING_DATA_FIELD_DEF(int64_t, normalCoreLoop);
31TILING_DATA_FIELD_DEF(int64_t, tailCoreLoop);
32END_TILING_DATA_DEF;
33 
34REGISTER_TILING_DATA_CLASS(IndexFillD, IndexFillDTilingData)
35 
36struct IndexFillDCompileInfo {
37 uint64_t coreNum = 0;
38 uint64_t ubSize = 0;
39};
40 
41class IndexFillDTiling : public TilingBaseClass
42{
43public:
44 explicit IndexFillDTiling(gert::TilingContext* context) : TilingBaseClass(context) {};
45 
46protected:
47 bool IsCapable() override;
48 ge::graphStatus GetShapeAttrsInfo() override;
49 ge::graphStatus GetPlatformInfo() override;
50 ge::graphStatus DoLibApiTiling() override;
51 uint64_t GetTilingKey() const override;
52 ge::graphStatus GetWorkspaceSize() override;
53 ge::graphStatus DoOpTiling() override;
54 ge::graphStatus PostTiling() override;
55 void DumpTilingInfo() override;
56 
57private:
58 ge::graphStatus CheckDataType();
59 ge::graphStatus CheckShape();
60 
61private:
62 ge::DataType dType_ = ge::DT_UNDEFINED;
63 gert::Shape inputXShape_;
64 int64_t inputShapeSize_ = 0;
65 int64_t ubSize_ = 0;
66 int64_t totalCoreNum_ = 0;
67 int64_t normalCoreData_ = 0;
68 int64_t tailCoreData_ = 0;
69 int64_t usedCoreNum_ = 0;
70 int64_t ubFactor_ = 0;
71 int64_t tailUbFactor_ = 0;
72 int64_t tailCoreTailUbFactor_ =0;
73 int64_t normalCoreLoop_ = 0;
74 int64_t tailCoreLoop_ = 0;
75 int64_t dataTypeSize_ = 1;
76 IndexFillDTilingData tilingData_;
77};
78 
79} // namespace optiling
80#endif // OPS_BUILD_IN_OP_TILING_RUNTIME_INDEX_FILL_D_TILING_H
Aindex/index_fill_d/op_host/config/ascend910_95/index_fill_d_binary.json+329-0
@@ -0,0 +1,329 @@
1{
2 "op_type": "IndexFillD",
3 "op_list": [
4 {
5 "bin_filename": "IndexFillD_8460c4b727ab5cc93a9595333a3fd571",
6 "inputs": [
7 {
8 "name": "x",
9 "index": 0,
10 "dtype": "float16",
11 "format": "ND",
12 "paramType": "required",
13 "shape": [
14 -2
15 ]
16 },
17 {
18 "name": "assist1",
19 "index": 1,
20 "dtype": "float16",
21 "format": "ND",
22 "paramType": "required",
23 "shape": [
24 -2
25 ]
26 },
27 {
28 "name": "assist2",
29 "index": 2,
30 "dtype": "float16",
31 "format": "ND",
32 "paramType": "required",
33 "shape": [
34 -2
35 ]
36 }
37 ],
38 "outputs": [
39 {
40 "name": "y",
41 "index": 0,
42 "dtype": "float16",
43 "format": "ND",
44 "paramType": "required",
45 "shape": [
46 -2
47 ]
48 }
49 ],
50 "attrs": [
51 {
52 "name": "dim",
53 "dtype": "int",
54 "value": null
55 }
56 ]
57 },
58 {
59 "bin_filename": "IndexFillD_3c918d330f983e55e90427727bb63ca4",
60 "inputs": [
61 {
62 "name": "x",
63 "index": 0,
64 "dtype": "float32",
65 "format": "ND",
66 "paramType": "required",
67 "shape": [
68 -2
69 ]
70 },
71 {
72 "name": "assist1",
73 "index": 1,
74 "dtype": "float32",
75 "format": "ND",
76 "paramType": "required",
77 "shape": [
78 -2
79 ]
80 },
81 {
82 "name": "assist2",
83 "index": 2,
84 "dtype": "float32",
85 "format": "ND",
86 "paramType": "required",
87 "shape": [
88 -2
89 ]
90 }
91 ],
92 "outputs": [
93 {
94 "name": "y",
95 "index": 0,
96 "dtype": "float32",
97 "format": "ND",
98 "paramType": "required",
99 "shape": [
100 -2
101 ]
102 }
103 ],
104 "attrs": [
105 {
106 "name": "dim",
107 "dtype": "int",
108 "value": null
109 }
110 ]
111 },
112 {
113 "bin_filename": "IndexFillD_7ccd2db7f704894c49645257024bf0e4",
114 "inputs": [
115 {
116 "name": "x",
117 "index": 0,
118 "dtype": "int32",
119 "format": "ND",
120 "paramType": "required",
121 "shape": [
122 -2
123 ]
124 },
125 {
126 "name": "assist1",
127 "index": 1,
128 "dtype": "int32",
129 "format": "ND",
130 "paramType": "required",
131 "shape": [
132 -2
133 ]
134 },
135 {
136 "name": "assist2",
137 "index": 2,
138 "dtype": "int32",
139 "format": "ND",
140 "paramType": "required",
141 "shape": [
142 -2
143 ]
144 }
145 ],
146 "outputs": [
147 {
148 "name": "y",
149 "index": 0,
150 "dtype": "int32",
151 "format": "ND",
152 "paramType": "required",
153 "shape": [
154 -2
155 ]
156 }
157 ],
158 "attrs": [
159 {
160 "name": "dim",
161 "dtype": "int",
162 "value": null
163 }
164 ]
165 },
166 {
167 "bin_filename": "IndexFillD_ND_bool_case",
168 "inputs": [
169 {
170 "name": "x",
171 "index": 0,
172 "dtype": "bool",
173 "format": "ND",
174 "paramType": "required",
175 "shape": [
176 -2
177 ]
178 },
179 {
180 "name": "assist1",
181 "index": 1,
182 "dtype": "bool",
183 "format": "ND",
184 "paramType": "required",
185 "shape": [
186 -2
187 ]
188 },
189 {
190 "name": "assist2",
191 "index": 2,
192 "dtype": "bool",
193 "format": "ND",
194 "paramType": "required",
195 "shape": [
196 -2
197 ]
198 }
199 ],
200 "outputs": [
201 {
202 "name": "y",
203 "index": 0,
204 "dtype": "bool",
205 "format": "ND",
206 "paramType": "required",
207 "shape": [
208 -2
209 ]
210 }
211 ],
212 "attrs": [
213 {
214 "name": "dim",
215 "dtype": "int",
216 "value": null
217 }
218 ]
219 },
220 {
221 "bin_filename": "IndexFillD_ND_int64_case",
222 "inputs": [
223 {
224 "name": "x",
225 "index": 0,
226 "dtype": "int64",
227 "format": "ND",
228 "paramType": "required",
229 "shape": [
230 -2
231 ]
232 },
233 {
234 "name": "assist1",
235 "index": 1,
236 "dtype": "int64",
237 "format": "ND",
238 "paramType": "required",
239 "shape": [
240 -2
241 ]
242 },
243 {
244 "name": "assist2",
245 "index": 2,
246 "dtype": "int64",
247 "format": "ND",
248 "paramType": "required",
249 "shape": [
250 -2
251 ]
252 }
253 ],
254 "outputs": [
255 {
256 "name": "y",
257 "index": 0,
258 "dtype": "int64",
259 "format": "ND",
260 "paramType": "required",
261 "shape": [
262 -2
263 ]
264 }
265 ],
266 "attrs": [
267 {
268 "name": "dim",
269 "dtype": "int",
270 "value": null
271 }
272 ]
273 },
274 {
275 "bin_filename": "IndexFillD_5dc191b64c07accb08e64c512612f056",
276 "inputs": [
277 {
278 "name": "x",
279 "index": 0,
280 "dtype": "bfloat16",
281 "format": "ND",
282 "paramType": "required",
283 "shape": [
284 -2
285 ]
286 },
287 {
288 "name": "assist1",
289 "index": 1,
290 "dtype": "bfloat16",
291 "format": "ND",
292 "paramType": "required",
293 "shape": [
294 -2
295 ]
296 },
297 {
298 "name": "assist2",
299 "index": 2,
300 "dtype": "bfloat16",
301 "format": "ND",
302 "paramType": "required",
303 "shape": [
304 -2
305 ]
306 }
307 ],
308 "outputs": [
309 {
310 "name": "y",
311 "index": 0,
312 "dtype": "bfloat16",
313 "format": "ND",
314 "paramType": "required",
315 "shape": [
316 -2
317 ]
318 }
319 ],
320 "attrs": [
321 {
322 "name": "dim",
323 "dtype": "int",
324 "value": null
325 }
326 ]
327 }
328 ]
329 }
Aindex/index_fill_d/op_host/config/ascend910_95/index_fill_d_simplified_key.ini+2-0
@@ -0,0 +1,2 @@
1[IndexFillD]
2default=0
Aindex/index_fill_d/op_host/index_fill_d_def.cpp+61-0
@@ -0,0 +1,61 @@
1/**
2 * Copyright (c) 2025 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 index_fill_d.cpp
13 * \brief index_fill_d op host
14 */
15#include "register/op_def_registry.h"
16 
17namespace ops {
18 
19class IndexFillD : public OpDef {
20public:
21 const std::vector<ge::DataType> xDataType = {
22 ge::DT_FLOAT16, ge::DT_FLOAT, ge::DT_BF16, ge::DT_INT64, ge::DT_INT32, ge::DT_BOOL};
23 const std::vector<ge::Format> xFormat = {
24 ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND};
25 explicit IndexFillD(const char* name) : OpDef(name) {
26 this->Input("x")
27 .ParamType(REQUIRED)
28 .DataType(xDataType)
29 .Format(xFormat)
30 .UnknownShapeFormat(xFormat);
31 this->Input("assist1")
32 .ParamType(REQUIRED)
33 .DataType(xDataType)
34 .Format(xFormat)
35 .UnknownShapeFormat(xFormat);
36 this->Input("assist2")
37 .ParamType(REQUIRED)
38 .DataType(xDataType)
39 .Format(xFormat)
40 .UnknownShapeFormat(xFormat);
41 this->Output("y")
42 .ParamType(REQUIRED)
43 .DataType(xDataType)
44 .Format(xFormat)
45 .UnknownShapeFormat(xFormat);
46 this->Attr("dim").AttrType(REQUIRED).Int();
47 
48 OpAICoreConfig aicore_config;
49 aicore_config.DynamicCompileStaticFlag(true)
50 .DynamicFormatFlag(false)
51 .DynamicRankSupportFlag(true)
52 .DynamicShapeSupportFlag(true)
53 .NeedCheckSupportFlag(false)
54 .ExtendCfgInfo("opFile.value", "index_fill_d_apt");
55 
56 this->AICore().AddConfig("ascend910_95", aicore_config);
57 }
58};
59 
60OP_ADD(IndexFillD);
61} // namespace ops
Aindex/index_fill_d/op_host/index_fill_d_infershape.cpp+18-0
@@ -0,0 +1,18 @@
1/**
2 * Copyright (c) 2025 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#include "op_host/infershape_elewise_util.h"
12#include "register/op_impl_registry.h"
13 
14using namespace ge;
15namespace ops
16{
17IMPL_OP_INFERSHAPE(IndexFillD).InferShape(Ops::Base::InferShape4Elewise);
18} // namespace ops
Aindex/index_fill_d/op_kernel/arch35/index_fill_d.h+163-0
@@ -0,0 +1,163 @@
1/**
2 * Copyright (c) 2025 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 index_fill_d.h
13 * \brief
14 */
15 
16#ifndef CANN_CUSTOM_OPS_INDEX_FILL_D_H
17#define CANN_CUSTOM_OPS_INDEX_FILL_D_H
18
19 
20using namespace AscendC;
CANN-robot
CANN-robotCANN-robot2025年12月28日

代码结构与可维护性: 在头文件中使用'using namespace AscendC;',可能导致命名空间污染,特别是当该头文件被多个源文件包含时,可能引起命名冲突。头文件中应避免使用using指令。

问题类型: 代码结构与可维护性 文件路径: index/index_fill_d/op_kernel/arch35/index_fill_d.h 行号: 20 问题代码:

using namespace AscendC;

修改建议:

移除该using指令,改为在需要使用AscendC中类型或函数的地方显式使用限定符,例如AscendC::GlobalTensor<T>。

此评论由代码审查工具自动生成

likedislike
daiwei18
daiwei18
2025年12月28日 评论:
likedislike
21static const int BUFFER_NUM = 2;
22template<typename T>
23class IndexFillD {
24public:
25 __aicore__ inline IndexFillD(const IndexFillDTilingData& tilingData, TPipe &pipe) :
26 tilingData_(tilingData), pipe_(pipe) {};
27 __aicore__ inline void Init(GM_ADDR x, GM_ADDR assist1, GM_ADDR assist2, GM_ADDR y, GM_ADDR workspace);
28 __aicore__ inline void CopyIn(int64_t offset, int64_t dataLen);
29 __aicore__ inline void CopyOut(int64_t offset, int64_t dataLen);
30 __aicore__ inline void Compute(int64_t dataLen);
31 __aicore__ inline void Process();
32 
33private:
34 GlobalTensor<T> xGm_;
35 GlobalTensor<T> assist1Gm_;
36 GlobalTensor<T> assist2Gm_;
37 GlobalTensor<T> yGm_;
38 TQue<QuePosition::VECIN, BUFFER_NUM> xQueue_;
39 TQue<QuePosition::VECIN, BUFFER_NUM> assist1Queue_;
40 TQue<QuePosition::VECIN, BUFFER_NUM> assist2Queue_;
41 TQue<QuePosition::VECOUT, BUFFER_NUM> yQueue_;
42 TPipe &pipe_;
43 const IndexFillDTilingData& tilingData_;
44};
45 
46template<typename T>
47__aicore__ inline void IndexFillD<T>::Init(GM_ADDR x, GM_ADDR assist1, GM_ADDR assist2, GM_ADDR y, GM_ADDR workspace)
48{
49 xGm_.SetGlobalBuffer((__gm__ T *)(x) + GetBlockIdx() * tilingData_.normalCoreData);
50 assist1Gm_.SetGlobalBuffer((__gm__ T *)(assist1) + GetBlockIdx() * tilingData_.normalCoreData);
51 assist2Gm_.SetGlobalBuffer((__gm__ T *)(assist2) + GetBlockIdx() * tilingData_.normalCoreData);
52 yGm_.SetGlobalBuffer((__gm__ T *)(y) + GetBlockIdx() * tilingData_.normalCoreData);
53 pipe_.InitBuffer(xQueue_, BUFFER_NUM, tilingData_.ubFactor * sizeof(T));
54 pipe_.InitBuffer(assist1Queue_, BUFFER_NUM, tilingData_.ubFactor * sizeof(T));
55 pipe_.InitBuffer(assist2Queue_, BUFFER_NUM, tilingData_.ubFactor * sizeof(T));
56 pipe_.InitBuffer(yQueue_, BUFFER_NUM, tilingData_.ubFactor * sizeof(T));
57}
58 
59template<typename T>
60__aicore__ inline void IndexFillD<T>::CopyIn(int64_t offset, int64_t dataLen)
61{
62 DataCopyExtParams inParams = { 1, static_cast<uint32_t>(dataLen * sizeof(T)), 0, 0, 0 };
63 DataCopyPadExtParams<T> padParams = { false, 0, 0, false };
64 LocalTensor<T> xLocal = xQueue_.AllocTensor<T>();
65 DataCopyPad(xLocal, xGm_[offset], inParams, padParams);
66 xQueue_.EnQue(xLocal);
67 
68 LocalTensor<T> assist1Local = assist1Queue_.AllocTensor<T>();
69 DataCopyPad(assist1Local, assist1Gm_[offset], inParams, padParams);
70 assist1Queue_.EnQue(assist1Local);
71 
72 LocalTensor<T> assist2Local = assist2Queue_.AllocTensor<T>();
73 DataCopyPad(assist2Local, assist2Gm_[offset], inParams, padParams);
74 assist2Queue_.EnQue(assist2Local);
75}
76 
77template<typename T>
78__aicore__ inline void IndexFillD<T>::CopyOut(int64_t offset, int64_t dataLen)
79{
80 DataCopyExtParams outParams = { 1, static_cast<uint32_t>(dataLen * sizeof(T)), 0, 0, 0 };
81 LocalTensor<T> yLocal = yQueue_.DeQue<T>();
82 DataCopyPad(yGm_[offset], yLocal, outParams);
83 yQueue_.FreeTensor(yLocal);
84}
85 
86template<typename T, typename DTYPE>
87static __aicore__ inline void CompareVf(LocalTensor<T> &xLocal, LocalTensor<T> &assist1Local,
88 LocalTensor<T> &assist2Local, LocalTensor<T> &yLocal,
89 uint32_t count, uint16_t onRepeatSize, uint16_t repeatTimes)
90{
91 __local_mem__ DTYPE* xPtr = (__local_mem__ DTYPE*)xLocal.GetPhyAddr();
92 __local_mem__ DTYPE* assist1Ptr = (__local_mem__ DTYPE*)assist1Local.GetPhyAddr();
93 __local_mem__ DTYPE* assist2Ptr = (__local_mem__ DTYPE*)assist2Local.GetPhyAddr();
94 __local_mem__ DTYPE* yPtr = (__local_mem__ DTYPE*)yLocal.GetPhyAddr();
95 __VEC_SCOPE__
96 {
97 MicroAPI::RegTensor<DTYPE> vSrcRegX;
98 MicroAPI::RegTensor<DTYPE> vSrcRegAssist1;
99 MicroAPI::RegTensor<DTYPE> vSrcRegAssist2;
100 MicroAPI::RegTensor<DTYPE> vDstRegY;
101 MicroAPI::MaskReg cmpMaskReg;
102 for(uint16_t i = 0; i < repeatTimes; i++) {
103 MicroAPI::MaskReg maskReg = MicroAPI::UpdateMask<DTYPE>(count);
104 MicroAPI::MaskReg maskAll = MicroAPI::CreateMask<DTYPE, MicroAPI::MaskPattern::ALL>();
105 MicroAPI::DataCopy(vSrcRegX, xPtr + i * onRepeatSize);
106 MicroAPI::DataCopy(vSrcRegAssist1, assist1Ptr + i * onRepeatSize);
107 MicroAPI::DataCopy(vSrcRegAssist2, assist2Ptr + i * onRepeatSize);
108 MicroAPI::CompareScalar<DTYPE, CMPMODE::GT>(cmpMaskReg, vSrcRegAssist1, (DTYPE)0, maskAll);
109 MicroAPI::Select(vDstRegY, vSrcRegX, vSrcRegAssist2, cmpMaskReg);
110 MicroAPI::DataCopy(yPtr + i * onRepeatSize, vDstRegY, maskReg);
111 }
112 }
113}
114 
115template<typename T>
116__aicore__ inline void IndexFillD<T>::Compute(int64_t dataLen)
117{
118 LocalTensor<T> xLocal = xQueue_.DeQue<T>();
119 LocalTensor<T> assist1Local = assist1Queue_.DeQue<T>();
120 LocalTensor<T> assist2Local = assist2Queue_.DeQue<T>();
121 LocalTensor<T> yLocal = yQueue_.AllocTensor<T>();
122 constexpr uint16_t onRepeatSize = GetVecLen() / sizeof(T);
123 uint16_t repeatNum = CeilDivision(dataLen, onRepeatSize);
124 if constexpr (std::is_same<T, bool>::value) {
125 CompareVf<T, int8_t>(xLocal, assist1Local, assist2Local, yLocal, (uint32_t)dataLen, onRepeatSize, repeatNum);
126 } else {
127 CompareVf<T, T>(xLocal, assist1Local, assist2Local, yLocal, (uint32_t)dataLen, onRepeatSize, repeatNum);
128 }
129 yQueue_.EnQue(yLocal);
130 xQueue_.FreeTensor(xLocal);
131 assist1Queue_.FreeTensor(assist1Local);
132 assist2Queue_.FreeTensor(assist2Local);
133}
134 
135template<typename T>
136__aicore__ inline void IndexFillD<T>::Process()
137{
138 if (GetBlockIdx() >= GetBlockNum()) {
139 return;
140 }
141 int64_t loopSize = tilingData_.normalCoreLoop;
142 int64_t tailUbFactor = tilingData_.tailUbFactor;
143 int64_t curCoreHandleData = tilingData_.normalCoreData;
144 if (GetBlockIdx() == GetBlockNum() - 1) {
145 loopSize = tilingData_.tailCoreLoop;
146 curCoreHandleData = tilingData_.tailCoreData;
147 tailUbFactor = tilingData_.tailCoreTailUbFactor;
148 }
149 int64_t offset = 0;
150 int64_t dataLen = tilingData_.ubFactor;
151 for (int64_t loopIdx = 0; loopIdx < loopSize - 1; loopIdx++) {
152 CopyIn(offset, dataLen);
153 Compute(dataLen);
154 CopyOut(offset, dataLen);
155 offset += dataLen;
156 }
157 dataLen = tailUbFactor;
158 CopyIn(offset, dataLen);
159 Compute(dataLen);
160 CopyOut(offset, dataLen);
161}
162 
163#endif // CANN_CUSTOM_OPS_INDEX_FILL_D_H
Aindex/index_fill_d/op_kernel/index_fill_d_apt.cpp+41-0
@@ -0,0 +1,41 @@
1/**
2 * Copyright (c) 2025 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 index_fill_d.cpp
13 * \brief
14 */
15#include "kernel_operator.h"
16#include "arch35/index_fill_d.h"
17 
18using namespace AscendC;
19 
20#define TILING_KEY_BOOL 101
21#define TILING_KEY_COMMON 200
22 
23 
24extern "C" __global__ __aicore__ void index_fill_d(GM_ADDR x, GM_ADDR assist1, GM_ADDR assist2,
25 GM_ADDR y, GM_ADDR workspace, GM_ADDR tiling)
26{
27 GM_ADDR userWS = GetUserWorkspace(workspace);
28 if (userWS == nullptr) {
29 return;
30 }
31 TPipe pipe;
32 GET_TILING_DATA(tilingData, tiling);
33 KERNEL_TASK_TYPE_DEFAULT(KERNEL_TYPE_AIV_ONLY);
34 
35 if (TILING_KEY_IS(TILING_KEY_COMMON)) {
36 IndexFillD<DTYPE_X> op(tilingData, pipe);
37 op.Init(x, assist1, assist2, y, userWS);
38 op.Process();
39 }
40 return;
41}
Mindex/index_fill_d/tests/CMakeLists.txt+5-8
@@ -1,18 +1,15 @@
1# ----------------------------------------------------------------------------1# -----------------------------------------------------------------------------------------------------------
2# Copyright (c) 2025 Huawei Technologies Co., Ltd.2# Copyright (c) 2025 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.
6# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8# See LICENSE in the root of the software repository for the full text of the License.
9# ----------------------------------------------------------------------------9# -----------------------------------------------------------------------------------------------------------
10 
11message(STATUS "=== Debug: start ops.math.is_finite.tests.CMakeLists.txt ")
12file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)10file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
13message(STATUS "=== Debug: CURRENT_DIRS =${CURRENT_DIRS} ")
14foreach(SUB_DIR ${CURRENT_DIRS})11foreach(SUB_DIR ${CURRENT_DIRS})
15 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")12 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")
16 add_subdirectory(${SUB_DIR})13 add_subdirectory(${SUB_DIR})
17 endif()14 endif()
18endforeach()15endforeach()
Mindex/index_fill_d/tests/ut/CMakeLists.txt+4-7
@@ -1,16 +1,13 @@
1# ----------------------------------------------------------------------------1# -----------------------------------------------------------------------------------------------------------
2# Copyright (c) 2025 Huawei Technologies Co., Ltd.2# Copyright (c) 2025 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.
6# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8# See LICENSE in the root of the software repository for the full text of the License.
9# ----------------------------------------------------------------------------9# -----------------------------------------------------------------------------------------------------------
10 
11# 每个目录下需要生成的可执行文件,具体参考:ops/built-in/test/CMakeLists.txt: 50~124
12file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)10file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
13message(STATUS "=== Debug: CURRENT_DIRS =${CURRENT_DIRS} ")
14foreach(SUB_DIR ${CURRENT_DIRS})11foreach(SUB_DIR ${CURRENT_DIRS})
15 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")12 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")
16 add_subdirectory(${SUB_DIR})13 add_subdirectory(${SUB_DIR})
Rindex/index_fill_d/op_host/CMakeLists.txtindex/index_fill_d/tests/ut/op_api/CMakeLists.txt+8-5
@@ -1,11 +1,14 @@
1# ----------------------------------------------------------------------------1# -----------------------------------------------------------------------------------------------------------
2# Copyright (c) 2025 Huawei Technologies Co., Ltd.2# Copyright (c) 2025 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.
6# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8# See LICENSE in the root of the software repository for the full text of the License.
9# ----------------------------------------------------------------------------9# -----------------------------------------------------------------------------------------------------------
10 10 
11add_modules_sources(HOSTNAME ${OPHOST_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR} OPTYPE index_fill_d ACLNNTYPE aclnn_exclude)11file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
12if(UT_TEST_ALL OR OP_API_UT)
13 add_modules_ut_sources(HOSTNAME ${OP_API_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})
14endif()
Rindex/index_fill_d/tests/ut/op_host/test_aclnn_index_fill_tensor.cppindex/index_fill_d/tests/ut/op_api/test_aclnn_index_fill_tensor.cpp+1-43
@@ -11,7 +11,7 @@
11#include <vector>11#include <vector>
12#include <array>12#include <array>
13#include "gtest/gtest.h"13#include "gtest/gtest.h"
14#include "../../../op_host/op_api/aclnn_index_fill_tensor.h"14#include "../../../op_api/aclnn_index_fill_tensor.h"
15#include "op_api_ut_common/tensor_desc.h"15#include "op_api_ut_common/tensor_desc.h"
16#include "op_api_ut_common/scalar_desc.h"16#include "op_api_ut_common/scalar_desc.h"
17#include "op_api_ut_common/op_api_ut.h"17#include "op_api_ut_common/op_api_ut.h"
@@ -42,9 +42,6 @@ TEST_F(l2_index_fill_tensor_test, test_index_fill_support_int32_out) {
42 uint64_t workspace_size = 0;42 uint64_t workspace_size = 0;
43 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);43 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
44 EXPECT_EQ(aclRet, ACL_SUCCESS);44 EXPECT_EQ(aclRet, ACL_SUCCESS);
45 
46 // SAMPLE: precision simulate
47 // ut.TestPrecision();
48}45}
49 46 
50TEST_F(l2_index_fill_tensor_test, test_index_fill_support_float16_out) {47TEST_F(l2_index_fill_tensor_test, test_index_fill_support_float16_out) {
@@ -62,9 +59,6 @@ TEST_F(l2_index_fill_tensor_test, test_index_fill_support_float16_out) {
62 uint64_t workspace_size = 0;59 uint64_t workspace_size = 0;
63 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);60 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
64 EXPECT_EQ(aclRet, ACL_SUCCESS);61 EXPECT_EQ(aclRet, ACL_SUCCESS);
65 
66 // SAMPLE: precision simulate
67 // ut.TestPrecision();
68}62}
69 63 
70TEST_F(l2_index_fill_tensor_test, test_index_fill_support_float32_out) {64TEST_F(l2_index_fill_tensor_test, test_index_fill_support_float32_out) {
@@ -82,9 +76,6 @@ TEST_F(l2_index_fill_tensor_test, test_index_fill_support_float32_out) {
82 uint64_t workspace_size = 0;76 uint64_t workspace_size = 0;
83 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);77 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
84 EXPECT_EQ(aclRet, ACL_SUCCESS);78 EXPECT_EQ(aclRet, ACL_SUCCESS);
85 
86 // SAMPLE: precision simulate
87 // ut.TestPrecision();
88}79}
89 80 
90// 正常场景 self:int32 fillVal:float81// 正常场景 self:int32 fillVal:float
@@ -103,9 +94,6 @@ TEST_F(l2_index_fill_tensor_test, test_index_fill_int32_float16_cast_out) {
103 uint64_t workspace_size = 0;94 uint64_t workspace_size = 0;
104 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);95 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
105 EXPECT_EQ(aclRet, ACL_SUCCESS);96 EXPECT_EQ(aclRet, ACL_SUCCESS);
106 
107 // SAMPLE: precision simulate
108 // ut.TestPrecision();
109}97}
110 98 
111TEST_F(l2_index_fill_tensor_test, test_index_fill_int32_float32_cast_out) {99TEST_F(l2_index_fill_tensor_test, test_index_fill_int32_float32_cast_out) {
@@ -123,9 +111,6 @@ TEST_F(l2_index_fill_tensor_test, test_index_fill_int32_float32_cast_out) {
123 uint64_t workspace_size = 0;111 uint64_t workspace_size = 0;
124 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);112 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
125 EXPECT_EQ(aclRet, ACL_SUCCESS);113 EXPECT_EQ(aclRet, ACL_SUCCESS);
126 
127 // SAMPLE: precision simulate
128 // ut.TestPrecision();
129}114}
130 115 
131TEST_F(l2_index_fill_tensor_test, test_index_fill_float16_int32_cast_out) {116TEST_F(l2_index_fill_tensor_test, test_index_fill_float16_int32_cast_out) {
@@ -143,9 +128,6 @@ TEST_F(l2_index_fill_tensor_test, test_index_fill_float16_int32_cast_out) {
143 uint64_t workspace_size = 0;128 uint64_t workspace_size = 0;
144 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);129 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
145 EXPECT_EQ(aclRet, ACL_SUCCESS);130 EXPECT_EQ(aclRet, ACL_SUCCESS);
146 
147 // SAMPLE: precision simulate
148 // ut.TestPrecision();
149}131}
150 132 
151TEST_F(l2_index_fill_tensor_test, test_index_fill_float32_int32_cast_out) {133TEST_F(l2_index_fill_tensor_test, test_index_fill_float32_int32_cast_out) {
@@ -163,9 +145,6 @@ TEST_F(l2_index_fill_tensor_test, test_index_fill_float32_int32_cast_out) {
163 uint64_t workspace_size = 0;145 uint64_t workspace_size = 0;
164 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);146 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
165 EXPECT_EQ(aclRet, ACL_SUCCESS);147 EXPECT_EQ(aclRet, ACL_SUCCESS);
166 
167 // SAMPLE: precision simulate
168 // ut.TestPrecision();
169}148}
170 149 
171// format test:HWCN150// format test:HWCN
@@ -184,9 +163,6 @@ TEST_F(l2_index_fill_tensor_test, test_index_fill_support_hwcn_out) {
184 uint64_t workspace_size = 0;163 uint64_t workspace_size = 0;
185 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);164 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
186 EXPECT_EQ(aclRet, ACL_SUCCESS);165 EXPECT_EQ(aclRet, ACL_SUCCESS);
187 
188 // SAMPLE: precision simulate
189 // ut.TestPrecision();
190}166}
191 167 
192TEST_F(l2_index_fill_tensor_test, test_index_fill_support_ncdhw_out) {168TEST_F(l2_index_fill_tensor_test, test_index_fill_support_ncdhw_out) {
@@ -204,9 +180,6 @@ TEST_F(l2_index_fill_tensor_test, test_index_fill_support_ncdhw_out) {
204 uint64_t workspace_size = 0;180 uint64_t workspace_size = 0;
205 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);181 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
206 EXPECT_EQ(aclRet, ACL_SUCCESS);182 EXPECT_EQ(aclRet, ACL_SUCCESS);
207 
208 // SAMPLE: precision simulate
209 // ut.TestPrecision();
210}183}
211 184 
212TEST_F(l2_index_fill_tensor_test, test_index_fill_support_ndhwc_out) {185TEST_F(l2_index_fill_tensor_test, test_index_fill_support_ndhwc_out) {
@@ -224,9 +197,6 @@ TEST_F(l2_index_fill_tensor_test, test_index_fill_support_ndhwc_out) {
224 uint64_t workspace_size = 0;197 uint64_t workspace_size = 0;
225 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);198 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
226 EXPECT_EQ(aclRet, ACL_SUCCESS);199 EXPECT_EQ(aclRet, ACL_SUCCESS);
227 
228 // SAMPLE: precision simulate
229 // ut.TestPrecision();
230}200}
231 201 
232TEST_F(l2_index_fill_tensor_test, test_index_fill_support_nhwc_out) {202TEST_F(l2_index_fill_tensor_test, test_index_fill_support_nhwc_out) {
@@ -244,9 +214,6 @@ TEST_F(l2_index_fill_tensor_test, test_index_fill_support_nhwc_out) {
244 uint64_t workspace_size = 0;214 uint64_t workspace_size = 0;
245 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);215 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
246 EXPECT_EQ(aclRet, ACL_SUCCESS);216 EXPECT_EQ(aclRet, ACL_SUCCESS);
247 
248 // SAMPLE: precision simulate
249 // ut.TestPrecision();
250}217}
251 218 
252TEST_F(l2_index_fill_tensor_test, test_index_fill_support_nchw_out) {219TEST_F(l2_index_fill_tensor_test, test_index_fill_support_nchw_out) {
@@ -264,9 +231,6 @@ TEST_F(l2_index_fill_tensor_test, test_index_fill_support_nchw_out) {
264 uint64_t workspace_size = 0;231 uint64_t workspace_size = 0;
265 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);232 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
266 EXPECT_EQ(aclRet, ACL_SUCCESS);233 EXPECT_EQ(aclRet, ACL_SUCCESS);
267 
268 // SAMPLE: precision simulate
269 // ut.TestPrecision();
270}234}
271 235 
272// dim < 0236// dim < 0
@@ -285,9 +249,6 @@ TEST_F(l2_index_fill_tensor_test, test_index_fill_support_minus_dim_out) {
285 uint64_t workspace_size = 0;249 uint64_t workspace_size = 0;
286 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);250 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
287 EXPECT_EQ(aclRet, ACL_SUCCESS);251 EXPECT_EQ(aclRet, ACL_SUCCESS);
288 
289 // SAMPLE: precision simulate
290 // ut.TestPrecision();
291}252}
292 253 
293// index < 0254// index < 0
@@ -306,9 +267,6 @@ TEST_F(l2_index_fill_tensor_test, test_index_fill_negative_index) {
306 uint64_t workspace_size = 0;267 uint64_t workspace_size = 0;
307 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);268 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
308 EXPECT_EQ(aclRet, ACL_SUCCESS);269 EXPECT_EQ(aclRet, ACL_SUCCESS);
309 
310 // SAMPLE: precision simulate
311 // ut.TestPrecision();
312}270}
313 271 
314TEST_F(l2_index_fill_tensor_test, test_index_fill_exceed_negative_index) {272TEST_F(l2_index_fill_tensor_test, test_index_fill_exceed_negative_index) {
Rindex/index_fill_d/tests/ut/op_host/test_aclnn_inplace_index_fill_tensor.cppindex/index_fill_d/tests/ut/op_api/test_aclnn_inplace_index_fill_tensor.cpp+1-40
@@ -11,7 +11,7 @@
11#include <vector>11#include <vector>
12#include <array>12#include <array>
13#include "gtest/gtest.h"13#include "gtest/gtest.h"
14#include "../../../op_host/op_api/aclnn_index_fill_tensor.h"14#include "../../../op_api/aclnn_index_fill_tensor.h"
15#include "op_api_ut_common/tensor_desc.h"15#include "op_api_ut_common/tensor_desc.h"
16#include "op_api_ut_common/scalar_desc.h"16#include "op_api_ut_common/scalar_desc.h"
17#include "op_api_ut_common/op_api_ut.h"17#include "op_api_ut_common/op_api_ut.h"
@@ -42,9 +42,6 @@ TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_int32) {
42 uint64_t workspace_size = 0;42 uint64_t workspace_size = 0;
43 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);43 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
44 EXPECT_EQ(aclRet, ACL_SUCCESS);44 EXPECT_EQ(aclRet, ACL_SUCCESS);
45 
46 // SAMPLE: precision simulate
47 // ut.TestPrecision();
48}45}
49 46 
50TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_float16) {47TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_float16) {
@@ -61,9 +58,6 @@ TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_float16) {
61 uint64_t workspace_size = 0;58 uint64_t workspace_size = 0;
62 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);59 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
63 EXPECT_EQ(aclRet, ACL_SUCCESS);60 EXPECT_EQ(aclRet, ACL_SUCCESS);
64 
65 // SAMPLE: precision simulate
66 // ut.TestPrecision();
67}61}
68 62 
69TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_float32) {63TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_float32) {
@@ -80,9 +74,6 @@ TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_float32) {
80 uint64_t workspace_size = 0;74 uint64_t workspace_size = 0;
81 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);75 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
82 EXPECT_EQ(aclRet, ACL_SUCCESS);76 EXPECT_EQ(aclRet, ACL_SUCCESS);
83 
84 // SAMPLE: precision simulate
85 // ut.TestPrecision();
86}77}
87 78 
88// 正常场景 self:int32 fillVal:float79// 正常场景 self:int32 fillVal:float
@@ -100,9 +91,6 @@ TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_int32_float16_cast) {
100 uint64_t workspace_size = 0;91 uint64_t workspace_size = 0;
101 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);92 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
102 EXPECT_EQ(aclRet, ACL_SUCCESS);93 EXPECT_EQ(aclRet, ACL_SUCCESS);
103 
104 // SAMPLE: precision simulate
105 // ut.TestPrecision();
106}94}
107 95 
108TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_int32_float32_cast) {96TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_int32_float32_cast) {
@@ -119,9 +107,6 @@ TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_int32_float32_cast) {
119 uint64_t workspace_size = 0;107 uint64_t workspace_size = 0;
120 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);108 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
121 EXPECT_EQ(aclRet, ACL_SUCCESS);109 EXPECT_EQ(aclRet, ACL_SUCCESS);
122 
123 // SAMPLE: precision simulate
124 // ut.TestPrecision();
125}110}
126 111 
127TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_float16_int32_cast) {112TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_float16_int32_cast) {
@@ -138,9 +123,6 @@ TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_float16_int32_cast) {
138 uint64_t workspace_size = 0;123 uint64_t workspace_size = 0;
139 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);124 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
140 EXPECT_EQ(aclRet, ACL_SUCCESS);125 EXPECT_EQ(aclRet, ACL_SUCCESS);
141 
142 // SAMPLE: precision simulate
143 // ut.TestPrecision();
144}126}
145 127 
146TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_float32_int32_cast) {128TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_float32_int32_cast) {
@@ -157,9 +139,6 @@ TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_float32_int32_cast) {
157 uint64_t workspace_size = 0;139 uint64_t workspace_size = 0;
158 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);140 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
159 EXPECT_EQ(aclRet, ACL_SUCCESS);141 EXPECT_EQ(aclRet, ACL_SUCCESS);
160 
161 // SAMPLE: precision simulate
162 // ut.TestPrecision();
163}142}
164 143 
165// format test:HWCN144// format test:HWCN
@@ -177,9 +156,6 @@ TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_hwcn) {
177 uint64_t workspace_size = 0;156 uint64_t workspace_size = 0;
178 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);157 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
179 EXPECT_EQ(aclRet, ACL_SUCCESS);158 EXPECT_EQ(aclRet, ACL_SUCCESS);
180 
181 // SAMPLE: precision simulate
182 // ut.TestPrecision();
183}159}
184 160 
185TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_ncdhw) {161TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_ncdhw) {
@@ -196,9 +172,6 @@ TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_ncdhw) {
196 uint64_t workspace_size = 0;172 uint64_t workspace_size = 0;
197 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);173 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
198 EXPECT_EQ(aclRet, ACL_SUCCESS);174 EXPECT_EQ(aclRet, ACL_SUCCESS);
199 
200 // SAMPLE: precision simulate
201 // ut.TestPrecision();
202}175}
203 176 
204TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_ndhwc) {177TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_ndhwc) {
@@ -215,9 +188,6 @@ TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_ndhwc) {
215 uint64_t workspace_size = 0;188 uint64_t workspace_size = 0;
216 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);189 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
217 EXPECT_EQ(aclRet, ACL_SUCCESS);190 EXPECT_EQ(aclRet, ACL_SUCCESS);
218 
219 // SAMPLE: precision simulate
220 // ut.TestPrecision();
221}191}
222 192 
223TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_nhwc) {193TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_nhwc) {
@@ -234,9 +204,6 @@ TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_nhwc) {
234 uint64_t workspace_size = 0;204 uint64_t workspace_size = 0;
235 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);205 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
236 EXPECT_EQ(aclRet, ACL_SUCCESS);206 EXPECT_EQ(aclRet, ACL_SUCCESS);
237 
238 // SAMPLE: precision simulate
239 // ut.TestPrecision();
240}207}
241 208 
242TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_nchw) {209TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_nchw) {
@@ -253,9 +220,6 @@ TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_nchw) {
253 uint64_t workspace_size = 0;220 uint64_t workspace_size = 0;
254 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);221 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
255 EXPECT_EQ(aclRet, ACL_SUCCESS);222 EXPECT_EQ(aclRet, ACL_SUCCESS);
256 
257 // SAMPLE: precision simulate
258 // ut.TestPrecision();
259}223}
260 224 
261// dim < 0225// dim < 0
@@ -273,9 +237,6 @@ TEST_F(l2_inplace_index_fill_tensor_test, test_index_fill_support_minus_dim) {
273 uint64_t workspace_size = 0;237 uint64_t workspace_size = 0;
274 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);238 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
275 EXPECT_EQ(aclRet, ACL_SUCCESS);239 EXPECT_EQ(aclRet, ACL_SUCCESS);
276 
277 // SAMPLE: precision simulate
278 // ut.TestPrecision();
279}240}
280 241 
281// self.dim > 8242// self.dim > 8
Mindex/index_fill_d/tests/ut/op_host/CMakeLists.txt+7-14
@@ -1,22 +1,15 @@
1 1# -----------------------------------------------------------------------------------------------------------
2#
3# Copyright (c) 2025 Huawei Technologies Co., Ltd.2# Copyright (c) 2025 Huawei Technologies Co., Ltd.
4# 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
5# CANN Open Software License Agreement Version 2.0 (the "License").4# CANN Open Software License Agreement Version 2.0 (the "License").
6# 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.
7# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 6# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
8# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.7# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
9# See LICENSE in the root of the software repository for the full text of the License.8# See LICENSE in the root of the software repository for the full text of the License.
10#/9# -----------------------------------------------------------------------------------------------------------
11 10 
12file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)11file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
13message(STATUS "=== Debug: CURRENT_DIRS =${CURRENT_DIRS} ")12if(UT_TEST_ALL OR OP_HOST_UT)
14foreach(SUB_DIR ${CURRENT_DIRS})13 add_modules_ut_sources(HOSTNAME ${OP_TILING_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})
15 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")14 add_modules_ut_sources(HOSTNAME ${OP_INFERSHAPE_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})
16 add_subdirectory(${SUB_DIR})
17 endif()
18endforeach()
19 
20if(UT_TEST_ALL OR OP_API_UT)
21 add_modules_ut_sources(HOSTNAME ${OP_API_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})
22endif()15endif()
Dindex/index_fill_d/tests/ut/op_host/test_aclnn_index_fill.cpp+0-166
@@ -1,166 +0,0 @@
1/**
2* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16 
17#include <vector>
18#include <array>
19#include "gtest/gtest.h"
20#include "../../../op_host/op_api/aclnn_index_fill.h"
21#include "op_api_ut_common/tensor_desc.h"
22#include "op_api_ut_common/scalar_desc.h"
23#include "op_api_ut_common/op_api_ut.h"
24 
25using namespace std;
26 
27class l2_index_fill_test : public testing::Test {
28 protected:
29 static void SetUpTestCase() {
30 cout << "index_fill_test SetUp" << endl;
31 }
32 
33 static void TearDownTestCase() { cout << "index_fill_test TearDown" << endl; }
34};
35 
36TEST_F(l2_index_fill_test, Ascend910B2_index_fill_case_00) {
37 int64_t dim = 1;
38 auto self = TensorDesc({2, 3}, ACL_INT32, ACL_FORMAT_ND)
39 .ValueRange(-10, 10)
40 .Value(vector<int32_t>{3, 4, 9, 6, 7, 11});
41 auto index = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND)
42 .ValueRange(0, 3)
43 .Value(vector<int32_t>{0, 1, 2});
44 auto fillVal = ScalarDesc(static_cast<int32_t>(1));
45 auto out = TensorDesc(self);
46 auto ut = OP_API_UT(aclnnIndexFill, INPUT(self, dim, index, fillVal), OUTPUT(out));
47 
48 // SAMPLE: only test GetWorkspaceSize
49 uint64_t workspace_size = 0;
50 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
51}
52 
53TEST_F(l2_index_fill_test, Ascend910B2_index_fill_case_01) {
54 int64_t dim = 1;
55 auto self = TensorDesc({2, 3}, ACL_FLOAT, ACL_FORMAT_ND)
56 .ValueRange(-10, 10)
57 .Value(vector<float>{3, 4, 9, 6, 7, 11});
58 auto index = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND)
59 .ValueRange(0, 3)
60 .Value(vector<int32_t>{0, 1, 2});
61 auto fillVal = ScalarDesc(static_cast<int32_t>(1));
62 auto out = TensorDesc(self);
63 auto ut = OP_API_UT(aclnnIndexFill, INPUT(self, dim, index, fillVal), OUTPUT(out));
64 
65 // SAMPLE: only test GetWorkspaceSize
66 uint64_t workspace_size = 0;
67 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
68}
69 
70TEST_F(l2_index_fill_test, Ascend910B2_index_fill_case_02) {
71 int64_t dim = 100;
72 auto self = TensorDesc({2, 3}, ACL_INT32, ACL_FORMAT_ND)
73 .ValueRange(-10, 10)
74 .Value(vector<int32_t>{3, 4, 9, 6, 7, 11});
75 auto index = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND)
76 .ValueRange(0, 3)
77 .Value(vector<int32_t>{0, 1, 2});
78 auto fillVal = ScalarDesc(static_cast<int32_t>(1));
79 auto out = TensorDesc(self);
80 auto ut = OP_API_UT(aclnnIndexFill, INPUT(self, dim, index, fillVal), OUTPUT(out));
81 
82 // SAMPLE: only test GetWorkspaceSize
83 uint64_t workspace_size = 0;
84 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
85}
86 
87TEST_F(l2_index_fill_test, Ascend910B2_index_fill_case_03) {
88 int64_t dim = 1;
89 auto self = TensorDesc({2, 3}, ACL_INT64, ACL_FORMAT_ND)
90 .ValueRange(-10, 10)
91 .Value(vector<int32_t>{3, 4, 9, 6, 7, 11});
92 auto index = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND)
93 .ValueRange(0, 3)
94 .Value(vector<int32_t>{0, 1, 2});
95 auto fillVal = ScalarDesc(static_cast<int64_t>(1));
96 auto out = TensorDesc(self);
97 auto ut = OP_API_UT(aclnnIndexFill, INPUT(self, dim, index, fillVal), OUTPUT(out));
98 
99 // SAMPLE: only test GetWorkspaceSize
100 uint64_t workspace_size = 0;
101 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
102}
103 
104TEST_F(l2_index_fill_test, Ascend910B2_index_fill_case_04) {
105 int64_t dim = 1;
106 auto self = TensorDesc({2, 3}, ACL_INT32, ACL_FORMAT_ND)
107 .ValueRange(-10, 10)
108 .Value(vector<int32_t>{3, 4, 9, 6, 7, 11});
109 auto index = TensorDesc({}, ACL_INT32, ACL_FORMAT_ND);
110 auto fillVal = ScalarDesc(static_cast<int32_t>(1));
111 auto out = TensorDesc(self);
112 auto ut = OP_API_UT(aclnnIndexFill, INPUT(self, dim, index, fillVal), OUTPUT(out));
113 
114 // SAMPLE: only test GetWorkspaceSize
115 uint64_t workspace_size = 0;
116 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
117}
118 
119TEST_F(l2_index_fill_test, Ascend910B2_index_fill_case_05) {
120 int64_t dim = 1;
121 auto self = TensorDesc({}, ACL_INT32, ACL_FORMAT_ND);
122 auto index = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND)
123 .ValueRange(0, 3)
124 .Value(vector<int32_t>{0, 1, 2});
125 auto fillVal = ScalarDesc(static_cast<int32_t>(1));
126 auto out = TensorDesc(self);
127 auto ut = OP_API_UT(aclnnIndexFill, INPUT(self, dim, index, fillVal), OUTPUT(out));
128 
129 // SAMPLE: only test GetWorkspaceSize
130 uint64_t workspace_size = 0;
131 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
132}
133 
134TEST_F(l2_index_fill_test, Ascend910B2_index_fill_case_06) {
135 int64_t dim = -100;
136 auto self = TensorDesc({2, 3}, ACL_INT32, ACL_FORMAT_ND)
137 .ValueRange(-10, 10)
138 .Value(vector<int32_t>{3, 4, 9, 6, 7, 11});
139 auto index = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND)
140 .ValueRange(0, 3)
141 .Value(vector<int32_t>{0, 1, 2});
142 auto fillVal = ScalarDesc(static_cast<int32_t>(1));
143 auto out = TensorDesc(self);
144 auto ut = OP_API_UT(aclnnIndexFill, INPUT(self, dim, index, fillVal), OUTPUT(out));
145 
146 // SAMPLE: only test GetWorkspaceSize
147 uint64_t workspace_size = 0;
148 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
149}
150 
151TEST_F(l2_index_fill_test, index_fill_case_07) {
152 int64_t dim = 1;
153 auto self = TensorDesc({2, 3}, ACL_INT32, ACL_FORMAT_ND)
154 .ValueRange(-10, 10)
155 .Value(vector<int32_t>{3, 4, 9, 6, 7, 11});
156 auto index = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND)
157 .ValueRange(0, 3)
158 .Value(vector<int32_t>{0, 1, 2});
159 auto fillVal = ScalarDesc(static_cast<int32_t>(1));
160 auto out = TensorDesc(self);
161 auto ut = OP_API_UT(aclnnIndexFill, INPUT(self, dim, index, fillVal), OUTPUT(out));
162 
163 // SAMPLE: only test GetWorkspaceSize
164 uint64_t workspace_size = 0;
165 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
166}
Dindex/index_fill_d/tests/ut/op_host/test_aclnn_inplace_index_fill.cpp+0-52
@@ -1,52 +0,0 @@
1/**
2* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16 
17#include <vector>
18#include <array>
19#include "gtest/gtest.h"
20#include "../../../op_host/op_api/aclnn_index_fill.h"
21#include "op_api_ut_common/tensor_desc.h"
22#include "op_api_ut_common/scalar_desc.h"
23#include "op_api_ut_common/op_api_ut.h"
24 
25using namespace std;
26 
27class l2_inplace_index_fill_test : public testing::Test {
28 protected:
29 static void SetUpTestCase() {
30 cout << "inpace_index_fill_test SetUp" << endl;
31 }
32 
33 static void TearDownTestCase() { cout << "inpace_index_fill_test TearDown" << endl; }
34};
35 
36// 正常场景 self:int32 fillVal:int32
37TEST_F(l2_inplace_index_fill_test, Ascend910B2_inplace_index_fill_case_00) {
38 int64_t dim = 1;
39 auto self = TensorDesc({2, 3}, ACL_INT32, ACL_FORMAT_ND)
40 .ValueRange(-10, 10)
41 .Value(vector<int32_t>{3, 4, 9, 6, 7, 11});
42 auto index = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND)
43 .ValueRange(0, 3)
44 .Value(vector<int32_t>{0, 1, 2});
45 auto fillVal = ScalarDesc(static_cast<int32_t>(1));
46 
47 auto ut = OP_API_UT(aclnnInplaceIndexFill, INPUT(self, dim, index, fillVal), OUTPUT());
48 
49 // SAMPLE: only test GetWorkspaceSize
50 uint64_t workspace_size = 0;
51 aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size);
52}
Mindex/index_fill_d/tests/ut/op_host/test_index_fill_d_infershape.cpp+74-1
@@ -11,4 +11,77 @@
11/*!11/*!
12 * \file test_index_fill_d_infershape.cpp12 * \file test_index_fill_d_infershape.cpp
13 * \brief13 * \brief
14 */14 */
15 
16#include "ut_op_util.h"
17#include "infershape_test_util.h"
18#include <iostream>
19#include "exe_graph/runtime/storage_format.h"
20#include "exe_graph/runtime/storage_shape.h"
21#include <gtest/gtest.h>
22#include "kernel_run_context_facker.h"
23#include "register/op_impl_registry.h"
24#include "log/log.h"
25#include "platform/platform_info.h"
26#include "../../../op_graph/index_fill_d_proto.h"
27#include "ut_op_common.h"
28 
29class IndexFillD : public testing::Test {
30protected:
31 static void SetUpTestCase()
32 {
33 std::cout << "IndexFillD SetUp" << std::endl;
34 }
35 
36 static void TearDownTestCase()
37 {
38 std::cout << "IndexFillD TearDown" << std::endl;
39 }
40};
41 
42TEST_F(IndexFillD, IndexFillD_infershape_case_1)
43{
44 ge::op::IndexFillD op;
45 op.UpdateInputDesc("x", create_desc({1000, 1000}, ge::DT_INT64));
46 op.UpdateInputDesc("assist1", create_desc({1000, 1000}, ge::DT_INT64));
47 op.UpdateInputDesc("assist2", create_desc({1000, 1000}, ge::DT_INT64));
48 op.SetAttr("dim", 0);
49 Runtime2TestParam param{{"dim"}, {}, {}};
50 EXPECT_EQ(InferShapeTest(op, param), ge::GRAPH_SUCCESS);
51 auto outputY = op.GetOutputDesc(0);
52 std::vector<int64_t> expectedYShape = {1000, 1000};
53 EXPECT_EQ(outputY.GetShape().GetDims(), expectedYShape);
54}
55 
56TEST_F(IndexFillD, IndexFillD_InferDtype_case_1)
57{
58 ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl("IndexFillD"), nullptr);
59 auto data_type_func = gert::OpImplRegistry::GetInstance().GetOpImpl("IndexFillD")->infer_datatype;
60 
61 if (data_type_func != nullptr) {
62 ge::DataType input_x_ref = ge::DT_INT64;
63 ge::DataType input_assist1_ref = ge::DT_INT64;
64 ge::DataType input_assist2_ref = ge::DT_INT64;
65 ge::DataType output_y_ref = ge::DT_INT64;
66 auto context_holder = gert::InferDataTypeContextFaker()
67 .IrInputNum(3)
68 .NodeIoNum(3, 1)
69 .NodeInputTd(0, ge::DT_INT64, ge::FORMAT_ND, ge::FORMAT_ND)
70 .NodeInputTd(1, ge::DT_INT64, ge::FORMAT_ND, ge::FORMAT_ND)
71 .NodeInputTd(2, ge::DT_INT64, ge::FORMAT_ND, ge::FORMAT_ND)
72 .NodeOutputTd(0, ge::DT_INT64, ge::FORMAT_ND, ge::FORMAT_ND)
73 .NodeAttrs(
74 {{"dim", Ops::NN::AnyValue::CreateFrom<int64_t>(0)}})
75 .InputDataTypes({&input_x_ref, &input_assist1_ref, &input_assist2_ref})
76 .OutputDataTypes({&output_y_ref})
77 .Build();
78 auto context = context_holder.GetContext<gert::InferDataTypeContext>();
79 EXPECT_EQ(data_type_func(context), ge::GRAPH_SUCCESS);
80 ASSERT_NE(context, nullptr);
81 
82 EXPECT_EQ(context->GetInputDataType(0), input_x_ref);
83 EXPECT_EQ(context->GetInputDataType(1), input_assist1_ref);
84 EXPECT_EQ(context->GetInputDataType(2), input_assist2_ref);
85 EXPECT_EQ(context->GetOutputDataType(0), output_y_ref);
86 }
87}
Mindex/index_fill_d/tests/ut/op_host/test_index_fill_d_tiling.cpp+159-1
@@ -11,4 +11,162 @@
11/*!11/*!
12 * \file test_index_fill_d_tiling.cpp12 * \file test_index_fill_d_tiling.cpp
13 * \brief13 * \brief
14 */14 */
15#include <iostream>
16#include <fstream>
17#include <vector>
18#include <gtest/gtest.h>
19#include "log/log.h"
20#include "kernel_run_context_facker.h"
21#include "test_cube_util.h"
22#include "exe_graph/runtime/storage_format.h"
23#include "exe_graph/runtime/storage_shape.h"
24#include "platform/platform_infos_def.h"
25#include "ut_op_util.h"
26#include "../../../op_host/arch35/index_fill_d_tiling.h"
27 
28using namespace ut_util;
29using namespace std;
30using namespace ge;
31 
32class IndexFillDTiling : public testing::Test {
33protected:
34 static void SetUpTestCase()
35 {
36 std::cout << "IndexFIllDTiling SetUp" << std::endl;
37 }
38 
39 static void TearDownTestCase()
40 {
41 std::cout << "IndexFIllDTiling TearDown" << std::endl;
42 }
43};
44 
45struct IndexFillDParamsInfo {
46 ge::DataType xDtype;
47 gert::StorageShape xShape;
48 gert::StorageShape assist1Shape;
49 gert::StorageShape assist2Shape;
50 gert::StorageShape yShape;
51};
52 
53template <typename T>
54static string ToString(void* buf, size_t size) {
55 std::string result;
56 const T* data = reinterpret_cast<const T*>(buf);
57 size_t len = size / sizeof(T);
58 for (size_t i = 0; i < len; i++) {
59 result += std::to_string(data[i]);
60 result += " ";
61 }
62 return result;
63}
64 
65static void ExecuteTestCase(const IndexFillDParamsInfo& opsParamInfos, string expectTilingData,
66 ge::graphStatus status = ge::GRAPH_SUCCESS)
67{
68 string compileInfoString = R"({
69 "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1",
70 "Intrinsic_fix_pipe_l0c2out": false, "Intrinsic_data_move_l12ub": true, "Intrinsic_data_move_l0c2ub": true, "Intrinsic_data_move_out2l1_nd2nz": false,
71 "UB_SIZE": 253952, "L2_SIZE": 33554432, "L1_SIZE": 524288,
72 "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072,
73 "CORE_NUM": 64}
74 })";
75 map<string, string> socInfos;
76 map<string, string> aicoreSpec;
77 map<string, string> intrinsics;
78 
79 GetPlatFormInfos(compileInfoString.c_str(), socInfos, aicoreSpec, intrinsics);
80 
81 // platform info
82 fe::PlatFormInfos platformInfo;
83 platformInfo.Init();
84 
85 // compile info
86 optiling::IndexFillDCompileInfo compileInfo;
87 compileInfo.coreNum = 64;
88 compileInfo.ubSize = 253952;
89 
90 std::string opType("IndexFillD");
91 ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(opType.c_str()), nullptr);
92 auto tilingFunc = gert::OpImplRegistry::GetInstance().GetOpImpl(opType.c_str())->tiling;
93 
94 // tilingFunc simulate
95 auto param = gert::TilingData::CreateCap(4096);
96 auto workspaceSizeHoler = gert::ContinuousVector::Create<size_t>(4096);
97 auto wsSize = reinterpret_cast<gert::ContinuousVector *>(workspaceSizeHoler.get());
98 ASSERT_NE(param, nullptr);
99 gert::StorageShape xShape = opsParamInfos.xShape;
100 gert::StorageShape assist1Shape = opsParamInfos.assist1Shape;
101 gert::StorageShape assist2Shape = opsParamInfos.assist2Shape;
102 gert::StorageShape yShape = opsParamInfos.yShape;
103 auto holder = gert::TilingContextFaker()
104 .NodeIoNum(3, 1)
105 .IrInstanceNum({1, 1, 1})
106 .InputShapes({&xShape, &assist1Shape, &assist2Shape})
107 .OutputShapes({&yShape})
108 .CompileInfo(&compileInfo)
109 .PlatformInfo(reinterpret_cast<char *>(&platformInfo))
110 .NodeInputTd(0, opsParamInfos.xDtype, ge::FORMAT_ND, ge::FORMAT_ND)
111 .NodeInputTd(1, opsParamInfos.xDtype, ge::FORMAT_ND, ge::FORMAT_ND)
112 .NodeInputTd(2, opsParamInfos.xDtype, ge::FORMAT_ND, ge::FORMAT_ND)
113 .NodeOutputTd(0, opsParamInfos.xDtype, ge::FORMAT_ND, ge::FORMAT_ND)
114 .TilingData(param.get())
115 .Workspace(wsSize)
116 .Build();
117 
118 gert::TilingContext* tilingContext = holder.GetContext<gert::TilingContext>();
119 ASSERT_NE(tilingContext, nullptr);
120 auto infos = tilingContext->GetPlatformInfo();
121 ASSERT_NE(infos, nullptr);
122 infos->SetPlatformRes("SoCInfo", socInfos);
123 infos->SetPlatformRes("AICoreSpec", aicoreSpec);
124 infos->SetCoreNumByCoreType("AICore");
125 infos->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics);
126 
127 // workspaces nullptr return failed
128 EXPECT_EQ(tilingFunc(tilingContext), status);
129 if (status == ge::GRAPH_FAILED) {
130 return;
131 }
132 // todo check tiling result
133 auto rawTilingData = tilingContext->GetRawTilingData();
134 auto tilingDataResult = ToString<int64_t>(rawTilingData->GetData(), rawTilingData->GetDataSize());
135 EXPECT_EQ(tilingDataResult, expectTilingData);
136}
137 
138TEST_F(IndexFillDTiling, IndexFillD_tiling_ascendc_bit_width_1) {
139 IndexFillDParamsInfo opsParamInfos;
140 opsParamInfos.xDtype = ge::DT_BOOL;
141 opsParamInfos.xShape = {{64, 32, 16, 1024}, {64, 32, 16, 1024}};
142 opsParamInfos.assist1Shape = opsParamInfos.xShape;
143 opsParamInfos.assist2Shape = opsParamInfos.xShape;
144 opsParamInfos.yShape = opsParamInfos.xShape;
145 string expectTilingData = "524288 524288 31744 16384 16384 17 17 ";
146 
147 ExecuteTestCase(opsParamInfos, expectTilingData);
148}
149 
150TEST_F(IndexFillDTiling, IndexFillD_tiling_ascendc_bit_width_2) {
151 IndexFillDParamsInfo opsParamInfos;
152 opsParamInfos.xDtype = ge::DT_FLOAT;
153 opsParamInfos.xShape = {{64, 32, 16, 1024}, {64, 32, 16, 1024}};
154 opsParamInfos.assist1Shape = opsParamInfos.xShape;
155 opsParamInfos.assist2Shape = opsParamInfos.xShape;
156 opsParamInfos.yShape = opsParamInfos.xShape;
157 string expectTilingData = "524288 524288 7680 2048 2048 69 69 ";
158 
159 ExecuteTestCase(opsParamInfos, expectTilingData);
160}
161 
162TEST_F(IndexFillDTiling, IndexFillD_tiling_ascendc_bit_width_4) {
163 IndexFillDParamsInfo opsParamInfos;
164 opsParamInfos.xDtype = ge::DT_INT32;
165 opsParamInfos.xShape = {{64, 32, 16, 1024}, {64, 32, 16, 1024}};
166 opsParamInfos.assist1Shape = opsParamInfos.xShape;
167 opsParamInfos.assist2Shape = opsParamInfos.xShape;
168 opsParamInfos.yShape = opsParamInfos.xShape;
169 string expectTilingData = "524288 524288 7680 2048 2048 69 69 ";
170 
171 ExecuteTestCase(opsParamInfos, expectTilingData);
172}
Mindex/index_put_v2/CMakeLists.txt+10-13
@@ -1,19 +1,16 @@
1#1# -----------------------------------------------------------------------------------------------------------
2# Copyright (c) 2025 Huawei Technologies Co., Ltd.2# Copyright (c) 2025 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.
6# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8# See LICENSE in the root of the software repository for the full text of the License.
9#/9# -----------------------------------------------------------------------------------------------------------
10 10 
11file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)11 
12if(NOT ENABLE_TEST AND NOT BENCHMARK)12# 设置算子定义时支持的芯片类型
13 list(REMOVE_ITEM CURRENT_DIRS tests)13set(SUPPORT_COMPUTE_UNIT "ascend910_95")
14endif()14# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译
15foreach(SUB_DIR ${CURRENT_DIRS})15set(SUPPORT_TILING_DIR "arch35")
16 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")16add_modules_sources(HOSTNAME ${OPHOST_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR} OPTYPE index_put_v2 ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE DEPENDENCIES index)
17 add_subdirectory(${SUB_DIR})
18 endif()
19endforeach()
Mindex/index_put_v2/README.md+91-2
@@ -1,3 +1,92 @@
1# IndexPutV21# IndexPutImpl
2 2 
3本目录仅包含IndexPutV2算子对应的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 800I A2 推理产品/A200I A2 Box 异构组件</term> | √ |
10 
11## 功能说明
12 
13- 接口功能:根据索引 indices 将输入 self 对应坐标的数据与输入 values 进行替换或累加。
14- 计算公式:
15 
16 - accumulate = False:
17 
18 $$
19 self[indices] = values
20 $$
21 
22 - accumulate = True:
23
24 $$
25 self[indices] = self[indices] + values
26 $$
27 
28 
29## 参数说明
30 
31 
32<table style="undefined;table-layout: fixed; width: 980px"><colgroup>
33 <col style="width: 100px">
34 <col style="width: 150px">
35 <col style="width: 280px">
36 <col style="width: 330px">
37 <col style="width: 120px">
38 </colgroup>
39 <thead>
40 <tr>
41 <th>参数名</th>
42 <th>输入/输出</th>
43 <th>描述</th>
44 <th>数据类型</th>
45 <th>数据格式</th>
46 </tr></thead>
47 <tbody>
48 <tr>
49 <td>selfRef</td>
50 <td>输入</td>
51 <td>公式中的 self。数据类型和values一致。</td>
52 <td>FLOAT、FLOAT16、DOUBLE、INT32、INT64、INT16、INT8、UINT8、BOOL、BFLOAT16</td>
53 <td>ND</td>
54 </tr>
55 <tr>
56 <td>indices</td>
57 <td>输入</td>
58 <td>公式中的 indices。</td>
59 <td>INT32、INT64、BOOL</td>
60 <td>ND</td>
61 </tr>
62 <tr>
63 <td>values</td>
64 <td>输入</td>
65 <td>公式中的 values。</td>
66 <td>和selfRef一致</td>
67 <td>ND</td>
68 </tr>
69 <tr>
70 <td>accumulate</td>
71 <td>输入</td>
72 <td>累加或更新的操作类型标志位,Host侧的布尔值。<ul><li>accumulate为True时为累加;</li><li>accumulate为False时为更新。</li></ul></td>
73 <td>-</td>
74 <td>-</td>
75 </tr>
76 <tr>
77 <td>unsafe</td>
78 <td>输入</td>
79 <td>检查索引是否在有效范围内标志位。<ul><li>unsafe为True时,索引越界会直接报错退出执行;</li><li>当unsafe为False时,如果出现了索引越界,就可能出现运行时异常。</li></ul></td>
80 <td>-</td>
81 <td>-</td>
82 </tr>
83 </tbody></table>
84 
85## 约束说明
86 
87
88## 调用说明
89 
90| 调用方式 | 调用样例 | 说明 |
91|--------------|------------------------------------------------------------------------|--------------------------------------------------------------|
92| aclnn调用 | [test_aclnn_index_put_v2](./examples/test_aclnn_index_put_v2.cpp) | 通过[aclnnAbs](./docs/aclnnIndexPutImpl.md)接口方式调用IndexPutImpl算子。 |
Mindex/index_put_v2/docs/aclnnIndexPutImpl.md+188-37
@@ -1,15 +1,18 @@
1# aclnnIndexPutImpl1# aclnnIndexPutImpl
2 2 
3[📄 查看源码](https://gitcode.com/cann/ops-nn/tree/master/index/index_put_v2)
4 
3## 产品支持情况5## 产品支持情况
4 6 
5| 产品 | 是否支持 |7| 产品 | 是否支持 |
6| :----------------------------------------------------------- | :------: |8| :----------------------------------------------------------- | :------: |
9| Ascend 950PR/Ascend 950DT</term> | √ |
7| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |10| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |
8| <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term> | √ |11| <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term> | √ |
9 12 
10## 功能说明13## 功能说明
11 14 
12- 算子功能:根据索引 indices 将输入 self 对应坐标的数据与输入 values 进行替换或累加。15- 接口功能:根据索引 indices 将输入 self 对应坐标的数据与输入 values 进行替换或累加。
13- 计算公式:16- 计算公式:
14 17 
15 - accumulate = False:18 - accumulate = False:
@@ -28,53 +31,201 @@
28 31 
29每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用“aclnnIndexPutImplGetWorkspaceSize”接口获取入参并根据计算流程计算所需workspace大小,再调用“aclnnIndexPutImpl”接口执行计算。32每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用“aclnnIndexPutImplGetWorkspaceSize”接口获取入参并根据计算流程计算所需workspace大小,再调用“aclnnIndexPutImpl”接口执行计算。
30 33 
31- `aclnnStatus aclnnIndexPutImplGetWorkspaceSize(aclTensor* selfRef, const aclTensorList* indices, const aclTensor* values, const bool accumulate, const bool unsafe, uint64_t* workspaceSize, aclOpExecutor** executor)`34```Cpp
32- `aclnnStatus aclnnIndexPutImpl(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream)`35aclnnStatus aclnnIndexPutImplGetWorkspaceSize(
36 aclTensor* selfRef,
37 const aclTensorList* indices,
38 const aclTensor* values,
39 const bool accumulate,
40 const bool unsafe,
41 uint64_t* workspaceSize,
42 aclOpExecutor** executor)
43```
44 
45```Cpp
46aclnnStatus aclnnIndexPutImpl(
47 void* workspace,
48 uint64_t workspaceSize,
49 aclOpExecutor* executor,
50 aclrtStream stream)
51```
33 52 
34## aclnnIndexPutImplGetWorkspaceSize53## aclnnIndexPutImplGetWorkspaceSize
35 54 
36* **参数说明**55* **参数说明**
37
38 * selfRef(aclTensor*,计算输入/输出):公式中的 $self$,Device侧的aclTensor,且数据类型和values一致,支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND,数据维度支持1-8维。
39 - <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term><term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT、FLOAT16、DOUBLE、INT32、INT64、INT16、INT8、UINT8、BOOL、BFLOAT16。
40 56 
41 * indices(aclTensorList*,计算输入):公式中的 $indices$,Device侧的aclTensorList,数据类型支持INT32、INT64、BOOL。[数据格式](../../../docs/zh/context/数据格式.md)支持ND。57 <table style="undefined;table-layout: fixed; width: 1477px"><colgroup>
58 <col style="width: 147px">
59 <col style="width: 120px">
60 <col style="width: 233px">
61 <col style="width: 277px">
62 <col style="width: 270px">
63 <col style="width: 121px">
64 <col style="width: 164px">
65 <col style="width: 145px">
66 </colgroup>
67 <thead>
68 <tr>
69 <th>参数名</th>
70 <th>输入/输出</th>
71 <th>描述</th>
72 <th>使用说明</th>
73 <th>数据类型</th>
74 <th>数据格式</th>
75 <th>维度(shape)</th>
76 <th>非连续Tensor</th>
77 </tr></thead>
78 <tbody>
79 <tr>
80 <td>selfRef</td>
81 <td>输入</td>
82 <td>公式中的 self。</td>
83 <td>数据类型和values一致。</td>
84 <td>FLOAT、FLOAT16、DOUBLE、INT32、INT64、INT16、INT8、UINT8、BOOL、BFLOAT16</td>
85 <td>ND</td>
86 <td>1-8</td>
87 <td>√</td>
88 </tr>
89 <tr>
90 <td>indices</td>
91 <td>输入</td>
92 <td>公式中的 indices。</td>
93 <td>-</td>
94 <td>INT32、INT64、BOOL</td>
95 <td>ND</td>
96 <td>-</td>
97 <td>-</td>
98 </tr>
99 <tr>
100 <td>values</td>
101 <td>输入</td>
102 <td>公式中的 values。</td>
103 <td>-</td>
104 <td>和selfRef一致</td>
105 <td>ND</td>
106 <td>-</td>
107 <td>-</td>
108 </tr>
109 <tr>
110 <td>accumulate</td>
111 <td>输入</td>
112 <td>累加或更新的操作类型标志位,Host侧的布尔值。</td>
113 <td><ul><li>accumulate为True时为累加;</li><li>accumulate为False时为更新。</li></ul></td>
114 <td>-</td>
115 <td>-</td>
116 <td>-</td>
117 <td>-</td>
118 </tr>
119 <tr>
120 <td>unsafe</td>
121 <td>输入</td>
122 <td>检查索引是否在有效范围内标志位。</td>
123 <td><ul><li>unsafe为True时,索引越界会直接报错退出执行;</li><li>当unsafe为False时,如果出现了索引越界,就可能出现运行时异常。</li></ul></td>
124 <td>-</td>
125 <td>-</td>
126 <td>-</td>
127 <td>-</td>
128 </tr>
129 <tr>
130 <td>workspaceSize</td>
131 <td>输出</td>
132 <td>返回需要在Device侧申请的workspace大小。</td>
133 <td>-</td>
134 <td>-</td>
135 <td>-</td>
136 <td>-</td>
137 <td>-</td>
138 </tr>
139 <tr>
140 <td>executor</td>
141 <td>输出</td>
142 <td>返回op执行器,包含了算子计算流程。</td>
143 <td>-</td>
144 <td>-</td>
145 <td>-</td>
146 <td>-</td>
147 <td>-</td>
148 </tr>
149 </tbody></table>
42 150 
43 * values(aclTensor*,计算输入):公式中的 $values$,Device侧的aclTensor,且数据类型和selfRef一致,[数据格式](../../../docs/zh/context/数据格式.md)支持ND151 - <term>Atlas 训练系列产品</term>:数据类型支持BFLOAT
44 - <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>数据类型支持FLOAT、FLOAT16、DOUBLE、INT32、INT64、INT16、INT8、UINT8、BOOL、BFLOAT16152 - Ascend 950PR/Ascend 950DT</term>:当accumulate为False,且indices有重复索引值的时候,结果不保序
45 153 
46 * accumulate(bool,计算输入):累加或更新的操作类型标志位,True为累加,False为更新,Host侧的布尔154* **返回**
47 * unsafe(bool,计算输入): 检查索引是否在有效范围内标志位。Host侧的布尔值。unsafe为True时,索引越界会直接报错退出执行;当unsafe为False时,如果出现了索引越界,就可能出现运行时异常。
48 
49 * workspaceSize(uint64_t\*,出参):返回需要在Device侧申请的workspace大小。
50 
51 * executor(aclOpExecutor\**,出参):返回op执行器,包含了算子计算流程。
52 
53* **返回值**
54 155 
55 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。156 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
56 157
57 ```
58 第一段接口完成入参校验,出现以下场景时报错:158 第一段接口完成入参校验,出现以下场景时报错:
59 返回161001(ACLNN_ERR_PARAM_NULLPTR):传入的selfRef、indices、values是空指针时。159 <table style="undefined;table-layout: fixed; width: 1244px"><colgroup>
60 返回161002(ACLNN_ERR_PARAM_INVALID):1. selfRef和values的数据类型不在支持的范围之内。160 <col style="width: 276px">
61 2. selfRef和values数据类型不同。161 <col style="width: 132px">
62 3. selfRef和values数据格式不同。162 <col style="width: 836px">
63 ```163 </colgroup>
164 <thead>
165 <tr>
166 <th>返回值</th>
167 <th>错误码</th>
168 <th>描述</th>
169 </tr></thead>
170 <tbody>
171 <tr>
172 <td>ACLNN_ERR_PARAM_NULLPTR</td>
173 <td>161001</td>
174 <td>传入的selfRef、indices、values是空指针时。</td>
175 </tr>
176 <tr>
177 <td rowspan="3">ACLNN_ERR_PARAM_INVALID</td>
178 <td rowspan="3">161002</td>
179 <td>selfRef和values的数据类型不在支持的范围之内。</td>
180 </tr>
181 <tr>
182 <td>selfRef和values数据类型不同。</td>
183 </tr>
184 <tr>
185 <td>selfRef和values数据格式不同。</td>
186 </tr>
187 </tbody>
188 </table>
64 189 
65## aclnnIndexPutImpl190## aclnnIndexPutImpl
66 191 
67- **参数说明**192- **参数说明**
68 193 <table style="undefined;table-layout: fixed; width: 1244px"><colgroup>
69 - workspace(void\*,入参):在Device侧申请的workspace内存地址。194 <col style="width: 200px">
70 195 <col style="width: 162px">
71 - workspaceSize(uint64_t,入参):在Device侧申请的workspace大小,由第一段接口aclnnIndexPutImplGetWorkspaceSize获取。196 <col style="width: 882px">
72 197 </colgroup>
73 - executor(aclOpExecutor\*,入参):op执行器,包含了算子计算流程。198 <thead>
74 199 <tr>
75 - stream(aclrtStream, 入): 指定执行任务的Stream。200 <th>数名</th>
76 201 <th>输入/输出</th>
77- **返回值**:202 <th>描述</th>
203 </tr></thead>
204 <tbody>
205 <tr>
206 <td>workspace</td>
207 <td>输入</td>
208 <td>在Device侧申请的workspace内存地址。</td>
209 </tr>
210 <tr>
211 <td>workspaceSize</td>
212 <td>输入</td>
213 <td>在Device侧申请的workspace大小,由第一段接口aclnnIndexPutImplGetWorkspaceSize获取。</td>
214 </tr>
215 <tr>
216 <td>executor</td>
217 <td>输入</td>
218 <td>op执行器,包含了算子计算流程。</td>
219 </tr>
220 <tr>
221 <td>stream</td>
222 <td>输入</td>
223 <td>指定执行任务的Stream。</td>
224 </tr>
225 </tbody>
226 </table>
227
228- **返回值**
78 229
79 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。230 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
80 231 
@@ -84,8 +235,8 @@
84 - aclnnIndexPutImpl默认非确定性实现,支持通过aclrtCtxSetSysParamOpt开启确定性。235 - aclnnIndexPutImpl默认非确定性实现,支持通过aclrtCtxSetSysParamOpt开启确定性。
85 236 
86- 输入参数selfRef, indices, values一般有以下约束:237- 输入参数selfRef, indices, values一般有以下约束:
87 - 1.indices中的Tensor个数不能超过selfRef的维度。238 - indices中的Tensor个数不能超过selfRef的维度。
88 - 2.values的维度需满足以下公式或广播后满足以下公式:239 - values的维度需满足以下公式或广播后满足以下公式:
89 - values.Dims() = indices[i].Dims() + (selfRef.Dims() - indices.size())240 - values.Dims() = indices[i].Dims() + (selfRef.Dims() - indices.size())
90 - 其意义是values前一半维度需要与indices中的Tensor维度相同(indices中的Tensor会广播成相同shape),后一半维度需要与selfRef维度扣除indices中Tensor个数后相同。241 - 其意义是values前一半维度需要与indices中的Tensor维度相同(indices中的Tensor会广播成相同shape),后一半维度需要与selfRef维度扣除indices中Tensor个数后相同。
91 242 
Rindex/index_put_v2/examples/test_aclnn_index_put_impl.cppindex/index_put_v2/examples/arch35/test_aclnn_index_put_v2.cpp+4-5
@@ -1,16 +1,15 @@
1/**1/**
2 * Copyright (c) 2025 Huawei Technologies Co., Ltd.2 * Copyright (c) 2025 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.
6 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8 * See LICENSE in the root of the software repository for the full text of the License.
9*/9 */
10 10
11#include <iostream>11#include <iostream>
12#include <vector>12#include <vector>
13#include <unistd.h>
14#include "acl/acl.h"13#include "acl/acl.h"
15#include "aclnnop/aclnn_index_put_impl.h"14#include "aclnnop/aclnn_index_put_impl.h"
16 15 
Rindex/index_put_v2/op_host/op_api/aclnn_index_put_impl.cppindex/index_put_v2/op_api/aclnn_index_put_impl.cpp+26-17
@@ -37,14 +37,18 @@
37#include "opdev/shape_utils.h"37#include "opdev/shape_utils.h"
38#include "opdev/platform.h"38#include "opdev/platform.h"
39#include "op_api/level2_base.h"39#include "op_api/level2_base.h"
40#if __has_include("runtime/context.h")
40#include "runtime/context.h"41#include "runtime/context.h"
42#else
43#include "runtime/runtime/context.h"
44#endif
41 45 
42using namespace op;46using namespace op;
43#ifdef __cplusplus47#ifdef __cplusplus
44extern "C" {48extern "C" {
45#endif49#endif
46 50 
47// 根据API定义,需要列出所能支持的所有dtype51// 根据API定义,需要列出所能支持的所有dtype
48static const std::initializer_list<op::DataType> DTYPE_SUPPORT_LIST = {52static const std::initializer_list<op::DataType> DTYPE_SUPPORT_LIST = {
49 op::DataType::DT_FLOAT, op::DataType::DT_INT32, op::DataType::DT_INT64, op::DataType::DT_FLOAT16,53 op::DataType::DT_FLOAT, op::DataType::DT_INT32, op::DataType::DT_INT64, op::DataType::DT_FLOAT16,
50 op::DataType::DT_INT16, op::DataType::DT_INT8, op::DataType::DT_UINT8, op::DataType::DT_DOUBLE,54 op::DataType::DT_INT16, op::DataType::DT_INT8, op::DataType::DT_UINT8, op::DataType::DT_DOUBLE,
@@ -771,9 +775,9 @@ static const aclTensor* AicpuProcess(const aclTensor* selfRef, const aclTensor*
771}775}
772 776 
773namespace {777namespace {
774static int32_t searchShape(FVector<const aclTensor*, DIMLIMIT>& allIndices, int i, int32_t index)778static int searchShape(FVector<const aclTensor*, DIMLIMIT>& allIndices, int i, int index)
775{779{
776 for (int j = 0; j < allIndices[index]->GetViewShape().GetDimNum(); j++) {780 for (int j = 0; j < static_cast<int>(allIndices[index]->GetViewShape().GetDimNum()); j++) {
777 if (allIndices[index]->GetViewShape()[j] < allIndices[i]->GetViewShape()[j]) {781 if (allIndices[index]->GetViewShape()[j] < allIndices[i]->GetViewShape()[j]) {
778 index = i;782 index = i;
779 break;783 break;
@@ -782,9 +786,9 @@ static int32_t searchShape(FVector<const aclTensor*, DIMLIMIT>& allIndices, int
782 return index;786 return index;
783}787}
784 788 
785static int32_t computeBroadCastShape(FVector<const aclTensor*, DIMLIMIT>& allIndices)789static int computeBroadCastShape(FVector<const aclTensor*, DIMLIMIT>& allIndices)
786{790{
787 int32_t index = 0;791 int index = 0;
788 for (int i = 1; i < static_cast<int>(allIndices.size()); i++) {792 for (int i = 1; i < static_cast<int>(allIndices.size()); i++) {
789 if (allIndices[index]->GetViewShape().GetDimNum() < allIndices[i]->GetViewShape().GetDimNum()) {793 if (allIndices[index]->GetViewShape().GetDimNum() < allIndices[i]->GetViewShape().GetDimNum()) {
790 index = i;794 index = i;
@@ -798,7 +802,7 @@ static int32_t computeBroadCastShape(FVector<const aclTensor*, DIMLIMIT>& allInd
798static bool isBroadCastShape(FVector<const aclTensor*, DIMLIMIT>& allIndices, int i, std::vector<int64_t> tensorShape, int32_t tensorShapeDim)802static bool isBroadCastShape(FVector<const aclTensor*, DIMLIMIT>& allIndices, int i, std::vector<int64_t> tensorShape, int32_t tensorShapeDim)
799{803{
800 bool needBroadcast = false;804 bool needBroadcast = false;
801 for (int32_t j = 0; j < tensorShapeDim; j++) {805 for (int j = 0; j < static_cast<int>(tensorShapeDim); j++) {
802 if (tensorShape[j] != allIndices[i]->GetViewShape()[j]) {806 if (tensorShape[j] != allIndices[i]->GetViewShape()[j]) {
803 needBroadcast = true;807 needBroadcast = true;
804 break;808 break;
@@ -810,7 +814,7 @@ static bool isBroadCastShape(FVector<const aclTensor*, DIMLIMIT>& allIndices, in
810static bool IndicesBroadcastUndeter(FVector<const aclTensor*, DIMLIMIT>& allIndices, aclOpExecutor* executor)814static bool IndicesBroadcastUndeter(FVector<const aclTensor*, DIMLIMIT>& allIndices, aclOpExecutor* executor)
811{815{
812 OP_LOGD("Enter IndicesBroadcast");816 OP_LOGD("Enter IndicesBroadcast");
813 int32_t index = computeBroadCastShape(allIndices);817 int index = computeBroadCastShape(allIndices);
814 bool needBroadcast = false;818 bool needBroadcast = false;
815 auto tensorShapeDim = allIndices[index]->GetViewShape().GetDimNum();819 auto tensorShapeDim = allIndices[index]->GetViewShape().GetDimNum();
816 std::vector<int64_t> tensorShape(tensorShapeDim);820 std::vector<int64_t> tensorShape(tensorShapeDim);
@@ -1037,8 +1041,7 @@ aclnnStatus aclnnIndexPutImplGetWorkspaceSize(aclTensor *selfRef,
1037 FVector<const aclTensor*, DIMLIMIT> definedIndices;1041 FVector<const aclTensor*, DIMLIMIT> definedIndices;
1038 ConstructStrideAndValue(selfCast, valueSize, stride);1042 ConstructStrideAndValue(selfCast, valueSize, stride);
1039 int64_t headNullNum = 0;1043 int64_t headNullNum = 0;
1040 bool isDiscontinueIdx = CheckIsDisContinueIdx(indices, headNullNum, definedIndices, uniqueExecutor.get());1044 (void)CheckIsDisContinueIdx(indices, headNullNum, definedIndices, uniqueExecutor.get());
1041 bool needTranspose = headNullNum;
1042 const aclTensor* indexPutOpOut;1045 const aclTensor* indexPutOpOut;
1043 FVector<int64_t, DIMLIMIT> masks;1046 FVector<int64_t, DIMLIMIT> masks;
1044 FVector<const aclTensor*, DIMLIMIT> allDefinedIndices;1047 FVector<const aclTensor*, DIMLIMIT> allDefinedIndices;
@@ -1087,9 +1090,16 @@ aclnnStatus aclnnIndexPutImplGetWorkspaceSize(aclTensor *selfRef,
1087 accumulate && deterministicValue == 1 &&1090 accumulate && deterministicValue == 1 &&
1088 (selfRef->GetDataType() == op::DataType::DT_FLOAT16 || selfRef->GetDataType() == op::DataType::DT_BF16);1091 (selfRef->GetDataType() == op::DataType::DT_FLOAT16 || selfRef->GetDataType() == op::DataType::DT_BF16);
1089 if (disDeterministicHighPrecision || DeterministicHighPrecision) {1092 if (disDeterministicHighPrecision || DeterministicHighPrecision) {
1090 OP_LOGD("Begin cast fp16, bf16, int8 or uint8 to fp32");1093 OP_LOGD("Begin cast fp16, bf16 to fp32");
1091 selfCast = l0op::Cast(selfRefContiguous, op::DataType::DT_FLOAT, uniqueExecutor.get());1094 if (selfRef->GetDataType() == op::DataType::DT_FLOAT16 || selfRef->GetDataType() == op::DataType::DT_BF16) {
1092 valuesCast = l0op::Cast(valuesContiguous, op::DataType::DT_FLOAT, uniqueExecutor.get());1095 selfCast = l0op::Cast(selfRefContiguous, op::DataType::DT_FLOAT, uniqueExecutor.get());
1096 valuesCast = l0op::Cast(valuesContiguous, op::DataType::DT_FLOAT, uniqueExecutor.get());
1097 }
1098 OP_LOGD("Begin cast int8, uint8 to int32");
1099 if (selfRef->GetDataType() == op::DataType::DT_INT8 || selfRef->GetDataType() == op::DataType::DT_UINT8) {
1100 selfCast = l0op::Cast(selfRefContiguous, op::DataType::DT_INT32, uniqueExecutor.get());
1101 valuesCast = l0op::Cast(valuesContiguous, op::DataType::DT_INT32, uniqueExecutor.get());
1102 }
1093 CHECK_RET(selfCast != nullptr, ACLNN_ERR_INNER_NULLPTR);1103 CHECK_RET(selfCast != nullptr, ACLNN_ERR_INNER_NULLPTR);
1094 CHECK_RET(valuesCast != nullptr, ACLNN_ERR_INNER_NULLPTR);1104 CHECK_RET(valuesCast != nullptr, ACLNN_ERR_INNER_NULLPTR);
1095 }1105 }
@@ -1108,7 +1118,6 @@ aclnnStatus aclnnIndexPutImplGetWorkspaceSize(aclTensor *selfRef,
1108 uniqueExecutor.ReleaseTo(executor); // 需要把 uniqueExecutor持有executor转移给executor1118 uniqueExecutor.ReleaseTo(executor); // 需要把 uniqueExecutor持有executor转移给executor
1109 return ACLNN_SUCCESS;1119 return ACLNN_SUCCESS;
1110 }1120 }
1111 bool isSupportAiCpu = IsAiCPUSupport(selfRef, allDefinedIndices, values, accumulate, masks);
1112 int64_t deterministicValue = 0;1121 int64_t deterministicValue = 0;
1113 rtError_t retRts = rtCtxGetSysParamOpt(SYS_OPT_DETERMINISTIC, &deterministicValue);1122 rtError_t retRts = rtCtxGetSysParamOpt(SYS_OPT_DETERMINISTIC, &deterministicValue);
1114 if (retRts != RT_ERROR_NONE) {1123 if (retRts != RT_ERROR_NONE) {
@@ -1161,7 +1170,7 @@ aclnnStatus aclnnIndexPutImplGetWorkspaceSize(aclTensor *selfRef,
1161 CHECK_RET(indexPutOpOut != nullptr, ACLNN_ERR_INNER_NULLPTR);1170 CHECK_RET(indexPutOpOut != nullptr, ACLNN_ERR_INNER_NULLPTR);
1162 } else {1171 } else {
1163 // 调用linearIndexV2时,以尾轴为单位,而不是以数为单位1172 // 调用linearIndexV2时,以尾轴为单位,而不是以数为单位
1164 int64_t indicesSize = static_cast<int64_t>(indices->Size());1173 indicesSize = static_cast<int64_t>(indices->Size());
1165 int64_t selfTailSize = indicesSize;1174 int64_t selfTailSize = indicesSize;
1166 int64_t selfRefSize = selfRef->GetViewShape().GetDimNum();1175 int64_t selfRefSize = selfRef->GetViewShape().GetDimNum();
1167 if (selfRefSize > indicesSize) {1176 if (selfRefSize > indicesSize) {
@@ -1169,7 +1178,7 @@ aclnnStatus aclnnIndexPutImplGetWorkspaceSize(aclTensor *selfRef,
1169 }1178 }
1170 FVector<int64_t, DIMLIMIT> selfTailShape(selfTailSize, 0);1179 FVector<int64_t, DIMLIMIT> selfTailShape(selfTailSize, 0);
1171 auto selfShape = selfRef->GetViewShape();1180 auto selfShape = selfRef->GetViewShape();
1172 for (size_t i = 0; i < indicesSize; i++) {1181 for (int64_t i = 0; i < indicesSize; i++) {
1173 selfTailShape[i] = selfShape.GetDim(i);1182 selfTailShape[i] = selfShape.GetDim(i);
1174 }1183 }
1175 if (selfRefSize > indicesSize) {1184 if (selfRefSize > indicesSize) {
@@ -1180,14 +1189,14 @@ aclnnStatus aclnnIndexPutImplGetWorkspaceSize(aclTensor *selfRef,
1180 FVector<int64_t, DIMLIMIT> valueSizeTail(selfTailSize, 0);1189 FVector<int64_t, DIMLIMIT> valueSizeTail(selfTailSize, 0);
1181 1190 
1182 valueSizeTail[selfTailSize - 1] = selfTailShape[selfTailSize - 1];1191 valueSizeTail[selfTailSize - 1] = selfTailShape[selfTailSize - 1];
1183 for (int32_t i = selfTailSize - 2; i >= 0; --i) {1192 for (int64_t i = selfTailSize - 2; i >= 0; --i) {
1184 valueSizeTail[i] = selfTailShape[i];1193 valueSizeTail[i] = selfTailShape[i];
1185 strideTail[i] = strideTail[i + 1] * valueSizeTail[i + 1];1194 strideTail[i] = strideTail[i + 1] * valueSizeTail[i + 1];
1186 }1195 }
1187 1196 
1188 int32_t sliceSize = 1;1197 int32_t sliceSize = 1;
1189 if (selfRefSize > indicesSize) {1198 if (selfRefSize > indicesSize) {
1190 for (size_t i = indicesSize; i < selfRefSize; i++) {1199 for (int64_t i = indicesSize; i < selfRefSize; i++) {
1191 sliceSize *= selfShape.GetDim(i);1200 sliceSize *= selfShape.GetDim(i);
1192 }1201 }
1193 }1202 }
Aindex/index_put_v2/op_api/aclnn_index_put_impl.h+53-0
@@ -0,0 +1,53 @@
1/**
2 * Copyright (c) 2025 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#ifndef OP_API_INC_INDEX_PUT_H_
11#define OP_API_INC_INDEX_PUT_H_
12 
13#include "aclnn/aclnn_base.h"
14#include "aclnn_util.h"
15 
16#ifdef __cplusplus
17extern "C" {
18#endif
19 
20/**
21 * @brief aclnnIndexPutImpl的第一段接口,根据具体的计算流程,计算workspace大小。
22 * @domain aclnn_ops_infer
23 * @param [in] selfRef: npu device侧的aclTensor,
24 * 数据类型支持FLOAT、FLOAT16、INT64、INT32、INT16、INT8、UINT8、BOOL、DOUBLE,支持非连续的Tensor,数据格式支持ND。
25 * @param [in] indices: npu device侧的aclTensorList,表示索引切片用。
26 * @param [in] values: npu device侧的aclTensor,索引处更新的值。
27 * @param [in] accumulate: bool 类型属性, True表示在索引处叠加value值, False表示在索引处替换value值。
28 * @param [in] unsafe: bool 类型属性。
29 * @param [out] workspaceSize: 返回用户需要在npu device侧申请的workspace大小。
30 * @param [out] executor: 返回op执行器,包含算子计算流程。
31 * @return aclnnStatus: 返回状态码。
32 */
33ACLNN_API aclnnStatus aclnnIndexPutImplGetWorkspaceSize(aclTensor* selfRef, const aclTensorList* indices,
34 const aclTensor* values, const bool accumulate,
35 const bool unsafe, uint64_t* workspaceSize,
36 aclOpExecutor** executor);
37 
38/**
39 * @brief aclnnIndexPutImpl的第二段接口,用于执行计算。
40 * @param [in] workspace: 在npu device侧申请的workspace内存起址。
41 * @param [in] workspaceSize: 在npu device侧申请的workspace大小,由第一段接口aaclnnIndexPutImplGetWorkspaceSize获取。
42 * @param [in] stream: acl stream流。
43 * @param [in] executor: op执行器,包含了算子计算流程。
44 * @return aclnnStatus: 返回状态码。
45 */
46ACLNN_API aclnnStatus aclnnIndexPutImpl(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor,
47 aclrtStream stream);
48 
49#ifdef __cplusplus
50}
51#endif
52 
53#endif // OP_API_INC_ADD_H_
Rindex/index_put_v2/op_host/op_api/index_put_v2.cppindex/index_put_v2/op_api/index_put_v2.cpp+0-0
文件重命名但无更改。
Aindex/index_put_v2/op_api/index_put_v2.h+29-0
@@ -0,0 +1,29 @@
1/**
2 * Copyright (c) 2025 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 index_put_v2.h
13 * \brief
14 */
15#ifndef PTA_NPU_OP_API_INC_LEVEL0_OP_INDEX_PUT_V2_OP_H_
16#define PTA_NPU_OP_API_INC_LEVEL0_OP_INDEX_PUT_V2_OP_H_
17 
18#include "opdev/op_executor.h"
19 
20namespace l0op {
21const aclTensor *IndexPutV2(const aclTensor *selfRef, const aclTensorList *indices, const aclTensor *values,
22 const aclTensor *masks, const bool accumulate, aclTensor *out, aclOpExecutor *executor);
23 
24const aclTensor *IndexPutV3(const aclTensor *selfRef, const aclTensorList *indices, const aclTensor *values,
25 const aclTensor *masks, const bool accumulate, const bool deterministic,
26 aclTensor *out, aclOpExecutor *executor);
27}
28#endif // PTA_NPU_OP_API_INC_LEVEL0_OP_INDEX_PUT_V2_OP_H_
29 
Aindex/index_put_v2/op_graph/index_put_v2_proto.h+50-0
@@ -0,0 +1,50 @@
1/**
2 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.
6 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 * See LICENSE in the root of the software repository for the full text of the License.
9 */
10 
11#ifndef OPS_BUILT_IN_OP_PROTO_INC_EXPERIMENT_OPS_H_
12#define OPS_BUILT_IN_OP_PROTO_INC_EXPERIMENT_OPS_H_
13 
14#include "graph/operator_reg.h"
15namespace ge {
16/**
17* @brief According to the index number of indexes, replace the value
18* corresponding to X with the value.
19 
20* @par Inputs:
21* Five inputs, including:
22* @li x: A ND Tensor. Must be one of the following types: int64, int32, float32, float16, bfloat16, int8, uint8, bool.
23* @li value: A Tensor of the same type as "x".
24* @li indexed_sizes: A 1D Tensor of int64 with shape (N). Sizes for each one of the indexed data.
25* @li indexed_strides: A 1D Tensor of int64 with shape (N). Strides for each one of the indexed data.
26* @li indices: Dynamic input. A ND Tensor of int64/int32. A Tensor of the indices.
27 
28* @par Attributes:
29* @li accumulate: Does it support self accumulation. Defaults to false.
30 
31* @par Outputs:
32* @li x: A Tensor.
33 
34* @par Third-party framework compatibility
35* Compatible with the Pytorch operator index_put.
36 
37* @par Restrictions:
38* Warning:THIS FUNCTION IS EXPERIMENTAL. Please do not use.
39*/
40REG_OP(IndexPutV2)
41 .INPUT(x, TensorType::BasicType())
42 .INPUT(value, TensorType::BasicType())
43 .INPUT(indexed_sizes, TensorType({DT_INT64}))
44 .INPUT(indexed_strides, TensorType({DT_INT64}))
45 .DYNAMIC_INPUT(indices, TensorType({DT_INT64, DT_INT32}))
46 .OUTPUT(x, TensorType::BasicType())
47 .ATTR(accumulate, Bool, false)
48 .OP_END_FACTORY_REG(IndexPutV2)
49} // namespace ge
50#endif
Aindex/index_put_v2/op_host/arch35/index_put_v2_tiling.cpp+62-0
@@ -0,0 +1,62 @@
1/**
2 * Copyright (c) 2025 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 index_put_v2.cc
13 * \brief IndexPutV2 tiling file
14 */
15#include <vector>
16#include "index_put_v2_tiling.h"
17#include "index/index/op_host/arch35/index_tiling_arch35.h"
18#include "register/op_impl_registry.h"
19#include "tiling/platform/platform_ascendc.h"
20#include "log/log.h"
21 
22namespace optiling {
23using namespace Ops::Base;
24 
25static ge::graphStatus Tiling4IndexPutV2(gert::TilingContext* context) {
26 OP_LOGD("indexputv2", "Tilingt2.0 start");
27 auto param = context->GetTilingData<IndexPutV2Params>();
28 OP_CHECK_NULL_WITH_CONTEXT(context, param);
29 auto compile_info = reinterpret_cast<const IndexPutV2CompileInfo*>(context->GetCompileInfo());
30 OP_LOGD(context->GetNodeName(), "Tiling4IndexPut dsl compile_info is Null, running Simt tiling.");
31 IndexSimtTiling tilingObj(context);
32 tilingObj.isIndexPut_ = true;
33 tilingObj.coreNum_ = compile_info->core_num;
34 tilingObj.ubSize_ = compile_info->ub_max_size;
35 return tilingObj.DoTiling();
36}
37 
38static ge::graphStatus TilingPrepare4IndexPutV2(gert::TilingParseContext* context){
39 OP_LOGD(context->GetNodeName(), "Start init TilingPrepare4IndexPutV2.");
40 auto ci = context->GetCompiledInfo<IndexPutV2CompileInfo>();
41 OP_CHECK_NULL_WITH_CONTEXT(context, ci);
42 auto platformInfo = context->GetPlatformInfo();
43 OP_CHECK_NULL_WITH_CONTEXT(context, platformInfo);
44 auto ascendcPlatform = platform_ascendc::PlatformAscendC(platformInfo);
45 ci->core_num = ascendcPlatform.GetCoreNumAiv();
46 OP_CHECK_IF((ci->core_num <= 0),
47 OP_LOGE(context->GetNodeName(), "Failed to core num."),
48 return ge::GRAPH_FAILED);
49 uint64_t ubSize;
50 ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::UB, ubSize);
51 ci->ub_max_size = static_cast<int64_t>(ubSize);
52 OP_CHECK_IF((ci->ub_max_size <= 0),
53 OP_LOGE(context->GetNodeName(), "Failed to get ub size."),
54 return ge::GRAPH_FAILED);
55 return ge::GRAPH_SUCCESS;
56}
57 
58// register tiling interface of the IndexPutV2 op.
59IMPL_OP_OPTILING(IndexPutV2)
60 .Tiling(Tiling4IndexPutV2)
61 .TilingParse<IndexPutV2CompileInfo>(TilingPrepare4IndexPutV2);
62} // namespace optiling
Aindex/index_put_v2/op_host/arch35/index_put_v2_tiling.h+64-0
@@ -0,0 +1,64 @@
1/**
2 * Copyright (c) 2025 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 index_put_v2.h
13 * \brief dsl index put tiling file
14 */
15#ifndef AIR_CXX_RUNTIME_V2_OP_IMPL_BOUNDING_BOX_DECODE_RUNTIME2_H
16#define AIR_CXX_RUNTIME_V2_OP_IMPL_BOUNDING_BOX_DECODE_RUNTIME2_H
17 
18#include <cstdint>
19namespace optiling {
20struct IndexPutV2CompileInfo {
21 int64_t ub_max_size;
22 int64_t x_data_each_block;
23 int64_t core_num;
24 int64_t each_repeat_block_number;
25 int64_t indices_count;
26 int64_t soc_version;
27};
28 
29struct IndexPutV2Params {
30 // calcu param
31 int64_t box_number;
32 int64_t core_data;
33 int64_t core_used;
34 int64_t copy_loop;
35 int64_t copy_tail;
36 int64_t last_copy_loop;
37 int64_t last_copy_tail;
38 int64_t reserver_dim_number;
39 int64_t value_number;
40 int64_t indices_number;
41 int64_t indices_list_number;
42 int64_t dim_0;
43 int64_t dim_1;
44 int64_t dim_2;
45 int64_t dim_3;
46 int64_t dim_4;
47 int64_t dim_5;
48 int64_t dim_6;
49 int64_t dim_7;
50 int64_t reserver_dim_0;
51 int64_t reserver_dim_1;
52 int64_t reserver_dim_2;
53 int64_t reserver_dim_3;
54 int64_t reserver_dim_4;
55 int64_t reserver_dim_5;
56 int64_t reserver_dim_6;
57 int64_t reserver_dim_7;
58 int64_t tiling_mode;
59 int64_t available_ub_size;
60 int64_t tiling_core_num;
61 int64_t mask_dim;
62};
63} // namespace optiling
64#endif // AIR_CXX_RUNTIME_V2_OP_IMPL_BOUNDING_BOX_DECODE_RUNTIME2_H
Aindex/index_put_v2/op_host/config/ascend910_95/index_put_v2_binary.json+2437-0
@@ -0,0 +1,2437 @@
1{
2 "op_type": "IndexPutV2",
3 "op_list": [
4 {
5 "bin_filename": "IndexPutV2_bool",
6 "inputs": [
7 {
8 "name": "x",
9 "index": 0,
10 "dtype": "bool",
11 "format": "ND",
12 "paramType": "required",
13 "shape": [
14 -2
15 ]
16 },
17 {
18 "name": "value",
19 "index": 1,
20 "dtype": "bool",
21 "format": "ND",
22 "paramType": "required",
23 "shape": [
24 -2
25 ]
26 },
27 {
28 "name": "indexed_sizes",
29 "index": 2,
30 "dtype": "int64",
31 "format": "ND",
32 "paramType": "required",
33 "shape": [
34 -2
35 ]
36 },
37 {
38 "name": "indexed_strides",
39 "index": 3,
40 "dtype": "int64",
41 "format": "ND",
42 "paramType": "required",
43 "shape": [
44 -2
45 ]
46 },
47 [
48 {
49 "name": "indices",
50 "index": 4,
51 "dtype": "int64",
52 "format": "ND",
53 "paramType": "dynamic",
54 "shape": [
55 -2
56 ]
57 }
58 ]
59 ],
60 "outputs": [
61 {
62 "name": "x",
63 "index": 0,
64 "dtype": "bool",
65 "format": "ND",
66 "paramType": "required",
67 "shape": [
68 -2
69 ]
70 }
71 ],
72 "attrs": [
73 {
74 "name": "accumulate",
75 "dtype": "bool",
76 "value": false
77 }
78 ]
79 },
80 {
81 "bin_filename": "IndexPutV2_bool_true",
82 "inputs": [
83 {
84 "name": "x",
85 "index": 0,
86 "dtype": "bool",
87 "format": "ND",
88 "paramType": "required",
89 "shape": [
90 -2
91 ]
92 },
93 {
94 "name": "value",
95 "index": 1,
96 "dtype": "bool",
97 "format": "ND",
98 "paramType": "required",
99 "shape": [
100 -2
101 ]
102 },
103 {
104 "name": "indexed_sizes",
105 "index": 2,
106 "dtype": "int64",
107 "format": "ND",
108 "paramType": "required",
109 "shape": [
110 -2
111 ]
112 },
113 {
114 "name": "indexed_strides",
115 "index": 3,
116 "dtype": "int64",
117 "format": "ND",
118 "paramType": "required",
119 "shape": [
120 -2
121 ]
122 },
123 [
124 {
125 "name": "indices",
126 "index": 4,
127 "dtype": "int64",
128 "format": "ND",
129 "paramType": "dynamic",
130 "shape": [
131 -2
132 ]
133 }
134 ]
135 ],
136 "outputs": [
137 {
138 "name": "x",
139 "index": 0,
140 "dtype": "bool",
141 "format": "ND",
142 "paramType": "required",
143 "shape": [
144 -2
145 ]
146 }
147 ],
148 "attrs": [
149 {
150 "name": "accumulate",
151 "dtype": "bool",
152 "value": true
153 }
154 ]
155 },
156 {
157 "bin_filename": "IndexPutV2_int8",
158 "inputs": [
159 {
160 "name": "x",
161 "index": 0,
162 "dtype": "int8",
163 "format": "ND",
164 "paramType": "required",
165 "shape": [
166 -2
167 ]
168 },
169 {
170 "name": "value",
171 "index": 1,
172 "dtype": "int8",
173 "format": "ND",
174 "paramType": "required",
175 "shape": [
176 -2
177 ]
178 },
179 {
180 "name": "indexed_sizes",
181 "index": 2,
182 "dtype": "int64",
183 "format": "ND",
184 "paramType": "required",
185 "shape": [
186 -2
187 ]
188 },
189 {
190 "name": "indexed_strides",
191 "index": 3,
192 "dtype": "int64",
193 "format": "ND",
194 "paramType": "required",
195 "shape": [
196 -2
197 ]
198 },
199 [
200 {
201 "name": "indices",
202 "index": 4,
203 "dtype": "int64",
204 "format": "ND",
205 "paramType": "dynamic",
206 "shape": [
207 -2
208 ]
209 }
210 ]
211 ],
212 "outputs": [
213 {
214 "name": "x",
215 "index": 0,
216 "dtype": "int8",
217 "format": "ND",
218 "paramType": "required",
219 "shape": [
220 -2
221 ]
222 }
223 ],
224 "attrs": [
225 {
226 "name": "accumulate",
227 "dtype": "bool",
228 "value": false
229 }
230 ]
231 },
232 {
233 "bin_filename": "IndexPutV2_int8_true",
234 "inputs": [
235 {
236 "name": "x",
237 "index": 0,
238 "dtype": "int8",
239 "format": "ND",
240 "paramType": "required",
241 "shape": [
242 -2
243 ]
244 },
245 {
246 "name": "value",
247 "index": 1,
248 "dtype": "int8",
249 "format": "ND",
250 "paramType": "required",
251 "shape": [
252 -2
253 ]
254 },
255 {
256 "name": "indexed_sizes",
257 "index": 2,
258 "dtype": "int64",
259 "format": "ND",
260 "paramType": "required",
261 "shape": [
262 -2
263 ]
264 },
265 {
266 "name": "indexed_strides",
267 "index": 3,
268 "dtype": "int64",
269 "format": "ND",
270 "paramType": "required",
271 "shape": [
272 -2
273 ]
274 },
275 [
276 {
277 "name": "indices",
278 "index": 4,
279 "dtype": "int64",
280 "format": "ND",
281 "paramType": "dynamic",
282 "shape": [
283 -2
284 ]
285 }
286 ]
287 ],
288 "outputs": [
289 {
290 "name": "x",
291 "index": 0,
292 "dtype": "int8",
293 "format": "ND",
294 "paramType": "required",
295 "shape": [
296 -2
297 ]
298 }
299 ],
300 "attrs": [
301 {
302 "name": "accumulate",
303 "dtype": "bool",
304 "value": true
305 }
306 ]
307 },
308 {
309 "bin_filename": "IndexPutV2_uint8",
310 "inputs": [
311 {
312 "name": "x",
313 "index": 0,
314 "dtype": "uint8",
315 "format": "ND",
316 "paramType": "required",
317 "shape": [
318 -2
319 ]
320 },
321 {
322 "name": "value",
323 "index": 1,
324 "dtype": "uint8",
325 "format": "ND",
326 "paramType": "required",
327 "shape": [
328 -2
329 ]
330 },
331 {
332 "name": "indexed_sizes",
333 "index": 2,
334 "dtype": "int64",
335 "format": "ND",
336 "paramType": "required",
337 "shape": [
338 -2
339 ]
340 },
341 {
342 "name": "indexed_strides",
343 "index": 3,
344 "dtype": "int64",
345 "format": "ND",
346 "paramType": "required",
347 "shape": [
348 -2
349 ]
350 },
351 [
352 {
353 "name": "indices",
354 "index": 4,
355 "dtype": "int64",
356 "format": "ND",
357 "paramType": "dynamic",
358 "shape": [
359 -2
360 ]
361 }
362 ]
363 ],
364 "outputs": [
365 {
366 "name": "x",
367 "index": 0,
368 "dtype": "uint8",
369 "format": "ND",
370 "paramType": "required",
371 "shape": [
372 -2
373 ]
374 }
375 ],
376 "attrs": [
377 {
378 "name": "accumulate",
379 "dtype": "bool",
380 "value": false
381 }
382 ]
383 },
384 {
385 "bin_filename": "IndexPutV2_uint8_true",
386 "inputs": [
387 {
388 "name": "x",
389 "index": 0,
390 "dtype": "uint8",
391 "format": "ND",
392 "paramType": "required",
393 "shape": [
394 -2
395 ]
396 },
397 {
398 "name": "value",
399 "index": 1,
400 "dtype": "uint8",
401 "format": "ND",
402 "paramType": "required",
403 "shape": [
404 -2
405 ]
406 },
407 {
408 "name": "indexed_sizes",
409 "index": 2,
410 "dtype": "int64",
411 "format": "ND",
412 "paramType": "required",
413 "shape": [
414 -2
415 ]
416 },
417 {
418 "name": "indexed_strides",
419 "index": 3,
420 "dtype": "int64",
421 "format": "ND",
422 "paramType": "required",
423 "shape": [
424 -2
425 ]
426 },
427 [
428 {
429 "name": "indices",
430 "index": 4,
431 "dtype": "int64",
432 "format": "ND",
433 "paramType": "dynamic",
434 "shape": [
435 -2
436 ]
437 }
438 ]
439 ],
440 "outputs": [
441 {
442 "name": "x",
443 "index": 0,
444 "dtype": "uint8",
445 "format": "ND",
446 "paramType": "required",
447 "shape": [
448 -2
449 ]
450 }
451 ],
452 "attrs": [
453 {
454 "name": "accumulate",
455 "dtype": "bool",
456 "value": true
457 }
458 ]
459 },
460 {
461 "bin_filename": "IndexPutV2_float16",
462 "inputs": [
463 {
464 "name": "x",
465 "index": 0,
466 "dtype": "float16",
467 "format": "ND",
468 "paramType": "required",
469 "shape": [
470 -2
471 ]
472 },
473 {
474 "name": "value",
475 "index": 1,
476 "dtype": "float16",
477 "format": "ND",
478 "paramType": "required",
479 "shape": [
480 -2
481 ]
482 },
483 {
484 "name": "indexed_sizes",
485 "index": 2,
486 "dtype": "int64",
487 "format": "ND",
488 "paramType": "required",
489 "shape": [
490 -2
491 ]
492 },
493 {
494 "name": "indexed_strides",
495 "index": 3,
496 "dtype": "int64",
497 "format": "ND",
498 "paramType": "required",
499 "shape": [
500 -2
501 ]
502 },
503 [
504 {
505 "name": "indices",
506 "index": 4,
507 "dtype": "int64",
508 "format": "ND",
509 "paramType": "dynamic",
510 "shape": [
511 -2
512 ]
513 }
514 ]
515 ],
516 "outputs": [
517 {
518 "name": "x",
519 "index": 0,
520 "dtype": "float16",
521 "format": "ND",
522 "paramType": "required",
523 "shape": [
524 -2
525 ]
526 }
527 ],
528 "attrs": [
529 {
530 "name": "accumulate",
531 "dtype": "bool",
532 "value": false
533 }
534 ]
535 },
536 {
537 "bin_filename": "IndexPutV2_float16_true",
538 "inputs": [
539 {
540 "name": "x",
541 "index": 0,
542 "dtype": "float16",
543 "format": "ND",
544 "paramType": "required",
545 "shape": [
546 -2
547 ]
548 },
549 {
550 "name": "value",
551 "index": 1,
552 "dtype": "float16",
553 "format": "ND",
554 "paramType": "required",
555 "shape": [
556 -2
557 ]
558 },
559 {
560 "name": "indexed_sizes",
561 "index": 2,
562 "dtype": "int64",
563 "format": "ND",
564 "paramType": "required",
565 "shape": [
566 -2
567 ]
568 },
569 {
570 "name": "indexed_strides",
571 "index": 3,
572 "dtype": "int64",
573 "format": "ND",
574 "paramType": "required",
575 "shape": [
576 -2
577 ]
578 },
579 [
580 {
581 "name": "indices",
582 "index": 4,
583 "dtype": "int64",
584 "format": "ND",
585 "paramType": "dynamic",
586 "shape": [
587 -2
588 ]
589 }
590 ]
591 ],
592 "outputs": [
593 {
594 "name": "x",
595 "index": 0,
596 "dtype": "float16",
597 "format": "ND",
598 "paramType": "required",
599 "shape": [
600 -2
601 ]
602 }
603 ],
604 "attrs": [
605 {
606 "name": "accumulate",
607 "dtype": "bool",
608 "value": true
609 }
610 ]
611 },
612 {
613 "bin_filename": "IndexPutV2_bfloat16",
614 "inputs": [
615 {
616 "name": "x",
617 "index": 0,
618 "dtype": "bfloat16",
619 "format": "ND",
620 "paramType": "required",
621 "shape": [
622 -2
623 ]
624 },
625 {
626 "name": "value",
627 "index": 1,
628 "dtype": "bfloat16",
629 "format": "ND",
630 "paramType": "required",
631 "shape": [
632 -2
633 ]
634 },
635 {
636 "name": "indexed_sizes",
637 "index": 2,
638 "dtype": "int64",
639 "format": "ND",
640 "paramType": "required",
641 "shape": [
642 -2
643 ]
644 },
645 {
646 "name": "indexed_strides",
647 "index": 3,
648 "dtype": "int64",
649 "format": "ND",
650 "paramType": "required",
651 "shape": [
652 -2
653 ]
654 },
655 [
656 {
657 "name": "indices",
658 "index": 4,
659 "dtype": "int64",
660 "format": "ND",
661 "paramType": "dynamic",
662 "shape": [
663 -2
664 ]
665 }
666 ]
667 ],
668 "outputs": [
669 {
670 "name": "x",
671 "index": 0,
672 "dtype": "bfloat16",
673 "format": "ND",
674 "paramType": "required",
675 "shape": [
676 -2
677 ]
678 }
679 ],
680 "attrs": [
681 {
682 "name": "accumulate",
683 "dtype": "bool",
684 "value": false
685 }
686 ]
687 },
688 {
689 "bin_filename": "IndexPutV2_bfloat16_true",
690 "inputs": [
691 {
692 "name": "x",
693 "index": 0,
694 "dtype": "bfloat16",
695 "format": "ND",
696 "paramType": "required",
697 "shape": [
698 -2
699 ]
700 },
701 {
702 "name": "value",
703 "index": 1,
704 "dtype": "bfloat16",
705 "format": "ND",
706 "paramType": "required",
707 "shape": [
708 -2
709 ]
710 },
711 {
712 "name": "indexed_sizes",
713 "index": 2,
714 "dtype": "int64",
715 "format": "ND",
716 "paramType": "required",
717 "shape": [
718 -2
719 ]
720 },
721 {
722 "name": "indexed_strides",
723 "index": 3,
724 "dtype": "int64",
725 "format": "ND",
726 "paramType": "required",
727 "shape": [
728 -2
729 ]
730 },
731 [
732 {
733 "name": "indices",
734 "index": 4,
735 "dtype": "int64",
736 "format": "ND",
737 "paramType": "dynamic",
738 "shape": [
739 -2
740 ]
741 }
742 ]
743 ],
744 "outputs": [
745 {
746 "name": "x",
747 "index": 0,
748 "dtype": "bfloat16",
749 "format": "ND",
750 "paramType": "required",
751 "shape": [
752 -2
753 ]
754 }
755 ],
756 "attrs": [
757 {
758 "name": "accumulate",
759 "dtype": "bool",
760 "value": true
761 }
762 ]
763 },
764 {
765 "bin_filename": "IndexPutV2_int32",
766 "inputs": [
767 {
768 "name": "x",
769 "index": 0,
770 "dtype": "int32",
771 "format": "ND",
772 "paramType": "required",
773 "shape": [
774 -2
775 ]
776 },
777 {
778 "name": "value",
779 "index": 1,
780 "dtype": "int32",
781 "format": "ND",
782 "paramType": "required",
783 "shape": [
784 -2
785 ]
786 },
787 {
788 "name": "indexed_sizes",
789 "index": 2,
790 "dtype": "int64",
791 "format": "ND",
792 "paramType": "required",
793 "shape": [
794 -2
795 ]
796 },
797 {
798 "name": "indexed_strides",
799 "index": 3,
800 "dtype": "int64",
801 "format": "ND",
802 "paramType": "required",
803 "shape": [
804 -2
805 ]
806 },
807 [
808 {
809 "name": "indices",
810 "index": 4,
811 "dtype": "int64",
812 "format": "ND",
813 "paramType": "dynamic",
814 "shape": [
815 -2
816 ]
817 }
818 ]
819 ],
820 "outputs": [
821 {
822 "name": "x",
823 "index": 0,
824 "dtype": "int32",
825 "format": "ND",
826 "paramType": "required",
827 "shape": [
828 -2
829 ]
830 }
831 ],
832 "attrs": [
833 {
834 "name": "accumulate",
835 "dtype": "bool",
836 "value": false
837 }
838 ]
839 },
840 {
841 "bin_filename": "IndexPutV2_int32_true",
842 "inputs": [
843 {
844 "name": "x",
845 "index": 0,
846 "dtype": "int32",
847 "format": "ND",
848 "paramType": "required",
849 "shape": [
850 -2
851 ]
852 },
853 {
854 "name": "value",
855 "index": 1,
856 "dtype": "int32",
857 "format": "ND",
858 "paramType": "required",
859 "shape": [
860 -2
861 ]
862 },
863 {
864 "name": "indexed_sizes",
865 "index": 2,
866 "dtype": "int64",
867 "format": "ND",
868 "paramType": "required",
869 "shape": [
870 -2
871 ]
872 },
873 {
874 "name": "indexed_strides",
875 "index": 3,
876 "dtype": "int64",
877 "format": "ND",
878 "paramType": "required",
879 "shape": [
880 -2
881 ]
882 },
883 [
884 {
885 "name": "indices",
886 "index": 4,
887 "dtype": "int64",
888 "format": "ND",
889 "paramType": "dynamic",
890 "shape": [
891 -2
892 ]
893 }
894 ]
895 ],
896 "outputs": [
897 {
898 "name": "x",
899 "index": 0,
900 "dtype": "int32",
901 "format": "ND",
902 "paramType": "required",
903 "shape": [
904 -2
905 ]
906 }
907 ],
908 "attrs": [
909 {
910 "name": "accumulate",
911 "dtype": "bool",
912 "value": true
913 }
914 ]
915 },
916 {
917 "bin_filename": "IndexPutV2_float32",
918 "inputs": [
919 {
920 "name": "x",
921 "index": 0,
922 "dtype": "float32",
923 "format": "ND",
924 "paramType": "required",
925 "shape": [
926 -2
927 ]
928 },
929 {
930 "name": "value",
931 "index": 1,
932 "dtype": "float32",
933 "format": "ND",
934 "paramType": "required",
935 "shape": [
936 -2
937 ]
938 },
939 {
940 "name": "indexed_sizes",
941 "index": 2,
942 "dtype": "int64",
943 "format": "ND",
944 "paramType": "required",
945 "shape": [
946 -2
947 ]
948 },
949 {
950 "name": "indexed_strides",
951 "index": 3,
952 "dtype": "int64",
953 "format": "ND",
954 "paramType": "required",
955 "shape": [
956 -2
957 ]
958 },
959 [
960 {
961 "name": "indices",
962 "index": 4,
963 "dtype": "int64",
964 "format": "ND",
965 "paramType": "dynamic",
966 "shape": [
967 -2
968 ]
969 }
970 ]
971 ],
972 "outputs": [
973 {
974 "name": "x",
975 "index": 0,
976 "dtype": "float32",
977 "format": "ND",
978 "paramType": "required",
979 "shape": [
980 -2
981 ]
982 }
983 ],
984 "attrs": [
985 {
986 "name": "accumulate",
987 "dtype": "bool",
988 "value": false
989 }
990 ]
991 },
992 {
993 "bin_filename": "IndexPutV2_float32_true",
994 "inputs": [
995 {
996 "name": "x",
997 "index": 0,
998 "dtype": "float32",
999 "format": "ND",
1000 "paramType": "required",
1001 "shape": [
1002 -2
1003 ]
1004 },
1005 {
1006 "name": "value",
1007 "index": 1,
1008 "dtype": "float32",
1009 "format": "ND",
1010 "paramType": "required",
1011 "shape": [
1012 -2
1013 ]
1014 },
1015 {
1016 "name": "indexed_sizes",
1017 "index": 2,
1018 "dtype": "int64",
1019 "format": "ND",
1020 "paramType": "required",
1021 "shape": [
1022 -2
1023 ]
1024 },
1025 {
1026 "name": "indexed_strides",
1027 "index": 3,
1028 "dtype": "int64",
1029 "format": "ND",
1030 "paramType": "required",
1031 "shape": [
1032 -2
1033 ]
1034 },
1035 [
1036 {
1037 "name": "indices",
1038 "index": 4,
1039 "dtype": "int64",
1040 "format": "ND",
1041 "paramType": "dynamic",
1042 "shape": [
1043 -2
1044 ]
1045 }
1046 ]
1047 ],
1048 "outputs": [
1049 {
1050 "name": "x",
1051 "index": 0,
1052 "dtype": "float32",
1053 "format": "ND",
1054 "paramType": "required",
1055 "shape": [
1056 -2
1057 ]
1058 }
1059 ],
1060 "attrs": [
1061 {
1062 "name": "accumulate",
1063 "dtype": "bool",
1064 "value": true
1065 }
1066 ]
1067 },
1068 {
1069 "bin_filename": "IndexPutV2_int64",
1070 "inputs": [
1071 {
1072 "name": "x",
1073 "index": 0,
1074 "dtype": "int64",
1075 "format": "ND",
1076 "paramType": "required",
1077 "shape": [
1078 -2
1079 ]
1080 },
1081 {
1082 "name": "value",
1083 "index": 1,
1084 "dtype": "int64",
1085 "format": "ND",
1086 "paramType": "required",
1087 "shape": [
1088 -2
1089 ]
1090 },
1091 {
1092 "name": "indexed_sizes",
1093 "index": 2,
1094 "dtype": "int64",
1095 "format": "ND",
1096 "paramType": "required",
1097 "shape": [
1098 -2
1099 ]
1100 },
1101 {
1102 "name": "indexed_strides",
1103 "index": 3,
1104 "dtype": "int64",
1105 "format": "ND",
1106 "paramType": "required",
1107 "shape": [
1108 -2
1109 ]
1110 },
1111 [
1112 {
1113 "name": "indices",
1114 "index": 4,
1115 "dtype": "int64",
1116 "format": "ND",
1117 "paramType": "dynamic",
1118 "shape": [
1119 -2
1120 ]
1121 }
1122 ]
1123 ],
1124 "outputs": [
1125 {
1126 "name": "x",
1127 "index": 0,
1128 "dtype": "int64",
1129 "format": "ND",
1130 "paramType": "required",
1131 "shape": [
1132 -2
1133 ]
1134 }
1135 ],
1136 "attrs": [
1137 {
1138 "name": "accumulate",
1139 "dtype": "bool",
1140 "value": false
1141 }
1142 ]
1143 },
1144 {
1145 "bin_filename": "IndexPutV2_int64_true",
1146 "inputs": [
1147 {
1148 "name": "x",
1149 "index": 0,
1150 "dtype": "int64",
1151 "format": "ND",
1152 "paramType": "required",
1153 "shape": [
1154 -2
1155 ]
1156 },
1157 {
1158 "name": "value",
1159 "index": 1,
1160 "dtype": "int64",
1161 "format": "ND",
1162 "paramType": "required",
1163 "shape": [
1164 -2
1165 ]
1166 },
1167 {
1168 "name": "indexed_sizes",
1169 "index": 2,
1170 "dtype": "int64",
1171 "format": "ND",
1172 "paramType": "required",
1173 "shape": [
1174 -2
1175 ]
1176 },
1177 {
1178 "name": "indexed_strides",
1179 "index": 3,
1180 "dtype": "int64",
1181 "format": "ND",
1182 "paramType": "required",
1183 "shape": [
1184 -2
1185 ]
1186 },
1187 [
1188 {
1189 "name": "indices",
1190 "index": 4,
1191 "dtype": "int64",
1192 "format": "ND",
1193 "paramType": "dynamic",
1194 "shape": [
1195 -2
1196 ]
1197 }
1198 ]
1199 ],
1200 "outputs": [
1201 {
1202 "name": "x",
1203 "index": 0,
1204 "dtype": "int64",
1205 "format": "ND",
1206 "paramType": "required",
1207 "shape": [
1208 -2
1209 ]
1210 }
1211 ],
1212 "attrs": [
1213 {
1214 "name": "accumulate",
1215 "dtype": "bool",
1216 "value": true
1217 }
1218 ]
1219 },
1220 {
1221 "bin_filename": "IndexPutV2_bool_int32",
1222 "inputs": [
1223 {
1224 "name": "x",
1225 "index": 0,
1226 "dtype": "bool",
1227 "format": "ND",
1228 "paramType": "required",
1229 "shape": [
1230 -2
1231 ]
1232 },
1233 {
1234 "name": "value",
1235 "index": 1,
1236 "dtype": "bool",
1237 "format": "ND",
1238 "paramType": "required",
1239 "shape": [
1240 -2
1241 ]
1242 },
1243 {
1244 "name": "indexed_sizes",
1245 "index": 2,
1246 "dtype": "int64",
1247 "format": "ND",
1248 "paramType": "required",
1249 "shape": [
1250 -2
1251 ]
1252 },
1253 {
1254 "name": "indexed_strides",
1255 "index": 3,
1256 "dtype": "int64",
1257 "format": "ND",
1258 "paramType": "required",
1259 "shape": [
1260 -2
1261 ]
1262 },
1263 [
1264 {
1265 "name": "indices",
1266 "index": 4,
1267 "dtype": "int32",
1268 "format": "ND",
1269 "paramType": "dynamic",
1270 "shape": [
1271 -2
1272 ]
1273 }
1274 ]
1275 ],
1276 "outputs": [
1277 {
1278 "name": "x",
1279 "index": 0,
1280 "dtype": "bool",
1281 "format": "ND",
1282 "paramType": "required",
1283 "shape": [
1284 -2
1285 ]
1286 }
1287 ],
1288 "attrs": [
1289 {
1290 "name": "accumulate",
1291 "dtype": "bool",
1292 "value": false
1293 }
1294 ]
1295 },
1296 {
1297 "bin_filename": "IndexPutV2_bool_in32_true",
1298 "inputs": [
1299 {
1300 "name": "x",
1301 "index": 0,
1302 "dtype": "bool",
1303 "format": "ND",
1304 "paramType": "required",
1305 "shape": [
1306 -2
1307 ]
1308 },
1309 {
1310 "name": "value",
1311 "index": 1,
1312 "dtype": "bool",
1313 "format": "ND",
1314 "paramType": "required",
1315 "shape": [
1316 -2
1317 ]
1318 },
1319 {
1320 "name": "indexed_sizes",
1321 "index": 2,
1322 "dtype": "int64",
1323 "format": "ND",
1324 "paramType": "required",
1325 "shape": [
1326 -2
1327 ]
1328 },
1329 {
1330 "name": "indexed_strides",
1331 "index": 3,
1332 "dtype": "int64",
1333 "format": "ND",
1334 "paramType": "required",
1335 "shape": [
1336 -2
1337 ]
1338 },
1339 [
1340 {
1341 "name": "indices",
1342 "index": 4,
1343 "dtype": "int32",
1344 "format": "ND",
1345 "paramType": "dynamic",
1346 "shape": [
1347 -2
1348 ]
1349 }
1350 ]
1351 ],
1352 "outputs": [
1353 {
1354 "name": "x",
1355 "index": 0,
1356 "dtype": "bool",
1357 "format": "ND",
1358 "paramType": "required",
1359 "shape": [
1360 -2
1361 ]
1362 }
1363 ],
1364 "attrs": [
1365 {
1366 "name": "accumulate",
1367 "dtype": "bool",
1368 "value": true
1369 }
1370 ]
1371 },
1372 {
1373 "bin_filename": "IndexPutV2_int8_in32",
1374 "inputs": [
1375 {
1376 "name": "x",
1377 "index": 0,
1378 "dtype": "int8",
1379 "format": "ND",
1380 "paramType": "required",
1381 "shape": [
1382 -2
1383 ]
1384 },
1385 {
1386 "name": "value",
1387 "index": 1,
1388 "dtype": "int8",
1389 "format": "ND",
1390 "paramType": "required",
1391 "shape": [
1392 -2
1393 ]
1394 },
1395 {
1396 "name": "indexed_sizes",
1397 "index": 2,
1398 "dtype": "int64",
1399 "format": "ND",
1400 "paramType": "required",
1401 "shape": [
1402 -2
1403 ]
1404 },
1405 {
1406 "name": "indexed_strides",
1407 "index": 3,
1408 "dtype": "int64",
1409 "format": "ND",
1410 "paramType": "required",
1411 "shape": [
1412 -2
1413 ]
1414 },
1415 [
1416 {
1417 "name": "indices",
1418 "index": 4,
1419 "dtype": "int32",
1420 "format": "ND",
1421 "paramType": "dynamic",
1422 "shape": [
1423 -2
1424 ]
1425 }
1426 ]
1427 ],
1428 "outputs": [
1429 {
1430 "name": "x",
1431 "index": 0,
1432 "dtype": "int8",
1433 "format": "ND",
1434 "paramType": "required",
1435 "shape": [
1436 -2
1437 ]
1438 }
1439 ],
1440 "attrs": [
1441 {
1442 "name": "accumulate",
1443 "dtype": "bool",
1444 "value": false
1445 }
1446 ]
1447 },
1448 {
1449 "bin_filename": "IndexPutV2_int8_in32_true",
1450 "inputs": [
1451 {
1452 "name": "x",
1453 "index": 0,
1454 "dtype": "int8",
1455 "format": "ND",
1456 "paramType": "required",
1457 "shape": [
1458 -2
1459 ]
1460 },
1461 {
1462 "name": "value",
1463 "index": 1,
1464 "dtype": "int8",
1465 "format": "ND",
1466 "paramType": "required",
1467 "shape": [
1468 -2
1469 ]
1470 },
1471 {
1472 "name": "indexed_sizes",
1473 "index": 2,
1474 "dtype": "int64",
1475 "format": "ND",
1476 "paramType": "required",
1477 "shape": [
1478 -2
1479 ]
1480 },
1481 {
1482 "name": "indexed_strides",
1483 "index": 3,
1484 "dtype": "int64",
1485 "format": "ND",
1486 "paramType": "required",
1487 "shape": [
1488 -2
1489 ]
1490 },
1491 [
1492 {
1493 "name": "indices",
1494 "index": 4,
1495 "dtype": "int32",
1496 "format": "ND",
1497 "paramType": "dynamic",
1498 "shape": [
1499 -2
1500 ]
1501 }
1502 ]
1503 ],
1504 "outputs": [
1505 {
1506 "name": "x",
1507 "index": 0,
1508 "dtype": "int8",
1509 "format": "ND",
1510 "paramType": "required",
1511 "shape": [
1512 -2
1513 ]
1514 }
1515 ],
1516 "attrs": [
1517 {
1518 "name": "accumulate",
1519 "dtype": "bool",
1520 "value": true
1521 }
1522 ]
1523 },
1524 {
1525 "bin_filename": "IndexPutV2_uint8_in32",
1526 "inputs": [
1527 {
1528 "name": "x",
1529 "index": 0,
1530 "dtype": "uint8",
1531 "format": "ND",
1532 "paramType": "required",
1533 "shape": [
1534 -2
1535 ]
1536 },
1537 {
1538 "name": "value",
1539 "index": 1,
1540 "dtype": "uint8",
1541 "format": "ND",
1542 "paramType": "required",
1543 "shape": [
1544 -2
1545 ]
1546 },
1547 {
1548 "name": "indexed_sizes",
1549 "index": 2,
1550 "dtype": "int64",
1551 "format": "ND",
1552 "paramType": "required",
1553 "shape": [
1554 -2
1555 ]
1556 },
1557 {
1558 "name": "indexed_strides",
1559 "index": 3,
1560 "dtype": "int64",
1561 "format": "ND",
1562 "paramType": "required",
1563 "shape": [
1564 -2
1565 ]
1566 },
1567 [
1568 {
1569 "name": "indices",
1570 "index": 4,
1571 "dtype": "int32",
1572 "format": "ND",
1573 "paramType": "dynamic",
1574 "shape": [
1575 -2
1576 ]
1577 }
1578 ]
1579 ],
1580 "outputs": [
1581 {
1582 "name": "x",
1583 "index": 0,
1584 "dtype": "uint8",
1585 "format": "ND",
1586 "paramType": "required",
1587 "shape": [
1588 -2
1589 ]
1590 }
1591 ],
1592 "attrs": [
1593 {
1594 "name": "accumulate",
1595 "dtype": "bool",
1596 "value": false
1597 }
1598 ]
1599 },
1600 {
1601 "bin_filename": "IndexPutV2_uint8_in32_true",
1602 "inputs": [
1603 {
1604 "name": "x",
1605 "index": 0,
1606 "dtype": "uint8",
1607 "format": "ND",
1608 "paramType": "required",
1609 "shape": [
1610 -2
1611 ]
1612 },
1613 {
1614 "name": "value",
1615 "index": 1,
1616 "dtype": "uint8",
1617 "format": "ND",
1618 "paramType": "required",
1619 "shape": [
1620 -2
1621 ]
1622 },
1623 {
1624 "name": "indexed_sizes",
1625 "index": 2,
1626 "dtype": "int64",
1627 "format": "ND",
1628 "paramType": "required",
1629 "shape": [
1630 -2
1631 ]
1632 },
1633 {
1634 "name": "indexed_strides",
1635 "index": 3,
1636 "dtype": "int64",
1637 "format": "ND",
1638 "paramType": "required",
1639 "shape": [
1640 -2
1641 ]
1642 },
1643 [
1644 {
1645 "name": "indices",
1646 "index": 4,
1647 "dtype": "int32",
1648 "format": "ND",
1649 "paramType": "dynamic",
1650 "shape": [
1651 -2
1652 ]
1653 }
1654 ]
1655 ],
1656 "outputs": [
1657 {
1658 "name": "x",
1659 "index": 0,
1660 "dtype": "uint8",
1661 "format": "ND",
1662 "paramType": "required",
1663 "shape": [
1664 -2
1665 ]
1666 }
1667 ],
1668 "attrs": [
1669 {
1670 "name": "accumulate",
1671 "dtype": "bool",
1672 "value": true
1673 }
1674 ]
1675 },
1676 {
1677 "bin_filename": "IndexPutV2_float16_in32",
1678 "inputs": [
1679 {
1680 "name": "x",
1681 "index": 0,
1682 "dtype": "float16",
1683 "format": "ND",
1684 "paramType": "required",
1685 "shape": [
1686 -2
1687 ]
1688 },
1689 {
1690 "name": "value",
1691 "index": 1,
1692 "dtype": "float16",
1693 "format": "ND",
1694 "paramType": "required",
1695 "shape": [
1696 -2
1697 ]
1698 },
1699 {
1700 "name": "indexed_sizes",
1701 "index": 2,
1702 "dtype": "int64",
1703 "format": "ND",
1704 "paramType": "required",
1705 "shape": [
1706 -2
1707 ]
1708 },
1709 {
1710 "name": "indexed_strides",
1711 "index": 3,
1712 "dtype": "int64",
1713 "format": "ND",
1714 "paramType": "required",
1715 "shape": [
1716 -2
1717 ]
1718 },
1719 [
1720 {
1721 "name": "indices",
1722 "index": 4,
1723 "dtype": "int32",
1724 "format": "ND",
1725 "paramType": "dynamic",
1726 "shape": [
1727 -2
1728 ]
1729 }
1730 ]
1731 ],
1732 "outputs": [
1733 {
1734 "name": "x",
1735 "index": 0,
1736 "dtype": "float16",
1737 "format": "ND",
1738 "paramType": "required",
1739 "shape": [
1740 -2
1741 ]
1742 }
1743 ],
1744 "attrs": [
1745 {
1746 "name": "accumulate",
1747 "dtype": "bool",
1748 "value": false
1749 }
1750 ]
1751 },
1752 {
1753 "bin_filename": "IndexPutV2_float16_in32_true",
1754 "inputs": [
1755 {
1756 "name": "x",
1757 "index": 0,
1758 "dtype": "float16",
1759 "format": "ND",
1760 "paramType": "required",
1761 "shape": [
1762 -2
1763 ]
1764 },
1765 {
1766 "name": "value",
1767 "index": 1,
1768 "dtype": "float16",
1769 "format": "ND",
1770 "paramType": "required",
1771 "shape": [
1772 -2
1773 ]
1774 },
1775 {
1776 "name": "indexed_sizes",
1777 "index": 2,
1778 "dtype": "int64",
1779 "format": "ND",
1780 "paramType": "required",
1781 "shape": [
1782 -2
1783 ]
1784 },
1785 {
1786 "name": "indexed_strides",
1787 "index": 3,
1788 "dtype": "int64",
1789 "format": "ND",
1790 "paramType": "required",
1791 "shape": [
1792 -2
1793 ]
1794 },
1795 [
1796 {
1797 "name": "indices",
1798 "index": 4,
1799 "dtype": "int32",
1800 "format": "ND",
1801 "paramType": "dynamic",
1802 "shape": [
1803 -2
1804 ]
1805 }
1806 ]
1807 ],
1808 "outputs": [
1809 {
1810 "name": "x",
1811 "index": 0,
1812 "dtype": "float16",
1813 "format": "ND",
1814 "paramType": "required",
1815 "shape": [
1816 -2
1817 ]
1818 }
1819 ],
1820 "attrs": [
1821 {
1822 "name": "accumulate",
1823 "dtype": "bool",
1824 "value": true
1825 }
1826 ]
1827 },
1828 {
1829 "bin_filename": "IndexPutV2_bfloat16_in32",
1830 "inputs": [
1831 {
1832 "name": "x",
1833 "index": 0,
1834 "dtype": "bfloat16",
1835 "format": "ND",
1836 "paramType": "required",
1837 "shape": [
1838 -2
1839 ]
1840 },
1841 {
1842 "name": "value",
1843 "index": 1,
1844 "dtype": "bfloat16",
1845 "format": "ND",
1846 "paramType": "required",
1847 "shape": [
1848 -2
1849 ]
1850 },
1851 {
1852 "name": "indexed_sizes",
1853 "index": 2,
1854 "dtype": "int64",
1855 "format": "ND",
1856 "paramType": "required",
1857 "shape": [
1858 -2
1859 ]
1860 },
1861 {
1862 "name": "indexed_strides",
1863 "index": 3,
1864 "dtype": "int64",
1865 "format": "ND",
1866 "paramType": "required",
1867 "shape": [
1868 -2
1869 ]
1870 },
1871 [
1872 {
1873 "name": "indices",
1874 "index": 4,
1875 "dtype": "int32",
1876 "format": "ND",
1877 "paramType": "dynamic",
1878 "shape": [
1879 -2
1880 ]
1881 }
1882 ]
1883 ],
1884 "outputs": [
1885 {
1886 "name": "x",
1887 "index": 0,
1888 "dtype": "bfloat16",
1889 "format": "ND",
1890 "paramType": "required",
1891 "shape": [
1892 -2
1893 ]
1894 }
1895 ],
1896 "attrs": [
1897 {
1898 "name": "accumulate",
1899 "dtype": "bool",
1900 "value": false
1901 }
1902 ]
1903 },
1904 {
1905 "bin_filename": "IndexPutV2_bfloat16_in32_true",
1906 "inputs": [
1907 {
1908 "name": "x",
1909 "index": 0,
1910 "dtype": "bfloat16",
1911 "format": "ND",
1912 "paramType": "required",
1913 "shape": [
1914 -2
1915 ]
1916 },
1917 {
1918 "name": "value",
1919 "index": 1,
1920 "dtype": "bfloat16",
1921 "format": "ND",
1922 "paramType": "required",
1923 "shape": [
1924 -2
1925 ]
1926 },
1927 {
1928 "name": "indexed_sizes",
1929 "index": 2,
1930 "dtype": "int64",
1931 "format": "ND",
1932 "paramType": "required",
1933 "shape": [
1934 -2
1935 ]
1936 },
1937 {
1938 "name": "indexed_strides",
1939 "index": 3,
1940 "dtype": "int64",
1941 "format": "ND",
1942 "paramType": "required",
1943 "shape": [
1944 -2
1945 ]
1946 },
1947 [
1948 {
1949 "name": "indices",
1950 "index": 4,
1951 "dtype": "int32",
1952 "format": "ND",
1953 "paramType": "dynamic",
1954 "shape": [
1955 -2
1956 ]
1957 }
1958 ]
1959 ],
1960 "outputs": [
1961 {
1962 "name": "x",
1963 "index": 0,
1964 "dtype": "bfloat16",
1965 "format": "ND",
1966 "paramType": "required",
1967 "shape": [
1968 -2
1969 ]
1970 }
1971 ],
1972 "attrs": [
1973 {
1974 "name": "accumulate",
1975 "dtype": "bool",
1976 "value": true
1977 }
1978 ]
1979 },
1980 {
1981 "bin_filename": "IndexPutV2_int32_in32",
1982 "inputs": [
1983 {
1984 "name": "x",
1985 "index": 0,
1986 "dtype": "int32",
1987 "format": "ND",
1988 "paramType": "required",
1989 "shape": [
1990 -2
1991 ]
1992 },
1993 {
1994 "name": "value",
1995 "index": 1,
1996 "dtype": "int32",
1997 "format": "ND",
1998 "paramType": "required",
1999 "shape": [
2000 -2
2001 ]
2002 },
2003 {
2004 "name": "indexed_sizes",
2005 "index": 2,
2006 "dtype": "int64",
2007 "format": "ND",
2008 "paramType": "required",
2009 "shape": [
2010 -2
2011 ]
2012 },
2013 {
2014 "name": "indexed_strides",
2015 "index": 3,
2016 "dtype": "int64",
2017 "format": "ND",
2018 "paramType": "required",
2019 "shape": [
2020 -2
2021 ]
2022 },
2023 [
2024 {
2025 "name": "indices",
2026 "index": 4,
2027 "dtype": "int32",
2028 "format": "ND",
2029 "paramType": "dynamic",
2030 "shape": [
2031 -2
2032 ]
2033 }
2034 ]
2035 ],
2036 "outputs": [
2037 {
2038 "name": "x",
2039 "index": 0,
2040 "dtype": "int32",
2041 "format": "ND",
2042 "paramType": "required",
2043 "shape": [
2044 -2
2045 ]
2046 }
2047 ],
2048 "attrs": [
2049 {
2050 "name": "accumulate",
2051 "dtype": "bool",
2052 "value": false
2053 }
2054 ]
2055 },
2056 {
2057 "bin_filename": "IndexPutV2_int32_in32_true",
2058 "inputs": [
2059 {
2060 "name": "x",
2061 "index": 0,
2062 "dtype": "int32",
2063 "format": "ND",
2064 "paramType": "required",
2065 "shape": [
2066 -2
2067 ]
2068 },
2069 {
2070 "name": "value",
2071 "index": 1,
2072 "dtype": "int32",
2073 "format": "ND",
2074 "paramType": "required",
2075 "shape": [
2076 -2
2077 ]
2078 },
2079 {
2080 "name": "indexed_sizes",
2081 "index": 2,
2082 "dtype": "int64",
2083 "format": "ND",
2084 "paramType": "required",
2085 "shape": [
2086 -2
2087 ]
2088 },
2089 {
2090 "name": "indexed_strides",
2091 "index": 3,
2092 "dtype": "int64",
2093 "format": "ND",
2094 "paramType": "required",
2095 "shape": [
2096 -2
2097 ]
2098 },
2099 [
2100 {
2101 "name": "indices",
2102 "index": 4,
2103 "dtype": "int32",
2104 "format": "ND",
2105 "paramType": "dynamic",
2106 "shape": [
2107 -2
2108 ]
2109 }
2110 ]
2111 ],
2112 "outputs": [
2113 {
2114 "name": "x",
2115 "index": 0,
2116 "dtype": "int32",
2117 "format": "ND",
2118 "paramType": "required",
2119 "shape": [
2120 -2
2121 ]
2122 }
2123 ],
2124 "attrs": [
2125 {
2126 "name": "accumulate",
2127 "dtype": "bool",
2128 "value": true
2129 }
2130 ]
2131 },
2132 {
2133 "bin_filename": "IndexPutV2_float32_in32",
2134 "inputs": [
2135 {
2136 "name": "x",
2137 "index": 0,
2138 "dtype": "float32",
2139 "format": "ND",
2140 "paramType": "required",
2141 "shape": [
2142 -2
2143 ]
2144 },
2145 {
2146 "name": "value",
2147 "index": 1,
2148 "dtype": "float32",
2149 "format": "ND",
2150 "paramType": "required",
2151 "shape": [
2152 -2
2153 ]
2154 },
2155 {
2156 "name": "indexed_sizes",
2157 "index": 2,
2158 "dtype": "int64",
2159 "format": "ND",
2160 "paramType": "required",
2161 "shape": [
2162 -2
2163 ]
2164 },
2165 {
2166 "name": "indexed_strides",
2167 "index": 3,
2168 "dtype": "int64",
2169 "format": "ND",
2170 "paramType": "required",
2171 "shape": [
2172 -2
2173 ]
2174 },
2175 [
2176 {
2177 "name": "indices",
2178 "index": 4,
2179 "dtype": "int32",
2180 "format": "ND",
2181 "paramType": "dynamic",
2182 "shape": [
2183 -2
2184 ]
2185 }
2186 ]
2187 ],
2188 "outputs": [
2189 {
2190 "name": "x",
2191 "index": 0,
2192 "dtype": "float32",
2193 "format": "ND",
2194 "paramType": "required",
2195 "shape": [
2196 -2
2197 ]
2198 }
2199 ],
2200 "attrs": [
2201 {
2202 "name": "accumulate",
2203 "dtype": "bool",
2204 "value": false
2205 }
2206 ]
2207 },
2208 {
2209 "bin_filename": "IndexPutV2_float32_in32_true",
2210 "inputs": [
2211 {
2212 "name": "x",
2213 "index": 0,
2214 "dtype": "float32",
2215 "format": "ND",
2216 "paramType": "required",
2217 "shape": [
2218 -2
2219 ]
2220 },
2221 {
2222 "name": "value",
2223 "index": 1,
2224 "dtype": "float32",
2225 "format": "ND",
2226 "paramType": "required",
2227 "shape": [
2228 -2
2229 ]
2230 },
2231 {
2232 "name": "indexed_sizes",
2233 "index": 2,
2234 "dtype": "int64",
2235 "format": "ND",
2236 "paramType": "required",
2237 "shape": [
2238 -2
2239 ]
2240 },
2241 {
2242 "name": "indexed_strides",
2243 "index": 3,
2244 "dtype": "int64",
2245 "format": "ND",
2246 "paramType": "required",
2247 "shape": [
2248 -2
2249 ]
2250 },
2251 [
2252 {
2253 "name": "indices",
2254 "index": 4,
2255 "dtype": "int32",
2256 "format": "ND",
2257 "paramType": "dynamic",
2258 "shape": [
2259 -2
2260 ]
2261 }
2262 ]
2263 ],
2264 "outputs": [
2265 {
2266 "name": "x",
2267 "index": 0,
2268 "dtype": "float32",
2269 "format": "ND",
2270 "paramType": "required",
2271 "shape": [
2272 -2
2273 ]
2274 }
2275 ],
2276 "attrs": [
2277 {
2278 "name": "accumulate",
2279 "dtype": "bool",
2280 "value": true
2281 }
2282 ]
2283 },
2284 {
2285 "bin_filename": "IndexPutV2_int64_in32",
2286 "inputs": [
2287 {
2288 "name": "x",
2289 "index": 0,
2290 "dtype": "int64",
2291 "format": "ND",
2292 "paramType": "required",
2293 "shape": [
2294 -2
2295 ]
2296 },
2297 {
2298 "name": "value",
2299 "index": 1,
2300 "dtype": "int64",
2301 "format": "ND",
2302 "paramType": "required",
2303 "shape": [
2304 -2
2305 ]
2306 },
2307 {
2308 "name": "indexed_sizes",
2309 "index": 2,
2310 "dtype": "int64",
2311 "format": "ND",
2312 "paramType": "required",
2313 "shape": [
2314 -2
2315 ]
2316 },
2317 {
2318 "name": "indexed_strides",
2319 "index": 3,
2320 "dtype": "int64",
2321 "format": "ND",
2322 "paramType": "required",
2323 "shape": [
2324 -2
2325 ]
2326 },
2327 [
2328 {
2329 "name": "indices",
2330 "index": 4,
2331 "dtype": "int32",
2332 "format": "ND",
2333 "paramType": "dynamic",
2334 "shape": [
2335 -2
2336 ]
2337 }
2338 ]
2339 ],
2340 "outputs": [
2341 {
2342 "name": "x",
2343 "index": 0,
2344 "dtype": "int64",
2345 "format": "ND",
2346 "paramType": "required",
2347 "shape": [
2348 -2
2349 ]
2350 }
2351 ],
2352 "attrs": [
2353 {
2354 "name": "accumulate",
2355 "dtype": "bool",
2356 "value": false
2357 }
2358 ]
2359 },
2360 {
2361 "bin_filename": "IndexPutV2_int64_in32_true",
2362 "inputs": [
2363 {
2364 "name": "x",
2365 "index": 0,
2366 "dtype": "int64",
2367 "format": "ND",
2368 "paramType": "required",
2369 "shape": [
2370 -2
2371 ]
2372 },
2373 {
2374 "name": "value",
2375 "index": 1,
2376 "dtype": "int64",
2377 "format": "ND",
2378 "paramType": "required",
2379 "shape": [
2380 -2
2381 ]
2382 },
2383 {
2384 "name": "indexed_sizes",
2385 "index": 2,
2386 "dtype": "int64",
2387 "format": "ND",
2388 "paramType": "required",
2389 "shape": [
2390 -2
2391 ]
2392 },
2393 {
2394 "name": "indexed_strides",
2395 "index": 3,
2396 "dtype": "int64",
2397 "format": "ND",
2398 "paramType": "required",
2399 "shape": [
2400 -2
2401 ]
2402 },
2403 [
2404 {
2405 "name": "indices",
2406 "index": 4,
2407 "dtype": "int32",
2408 "format": "ND",
2409 "paramType": "dynamic",
2410 "shape": [
2411 -2
2412 ]
2413 }
2414 ]
2415 ],
2416 "outputs": [
2417 {
2418 "name": "x",
2419 "index": 0,
2420 "dtype": "int64",
2421 "format": "ND",
2422 "paramType": "required",
2423 "shape": [
2424 -2
2425 ]
2426 }
2427 ],
2428 "attrs": [
2429 {
2430 "name": "accumulate",
2431 "dtype": "bool",
2432 "value": true
2433 }
2434 ]
2435 }
2436 ]
2437 }
Aindex/index_put_v2/op_host/config/ascend910_95/index_put_v2_simplified_key.ini+2-0
@@ -0,0 +1,2 @@
1[IndexPutV2]
2default=0
Aindex/index_put_v2/op_host/index_put_v2_def.cpp+68-0
@@ -0,0 +1,68 @@
1/**
2 * Copyright (c) 2025 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 index_put_v2.cpp
13 * \brief IndexPutV2 ophost
14 */
15#include "register/op_def_registry.h"
16namespace {
17static const std::vector<ge::Format> format = {ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND,
18 ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND,
19 ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND,
20 ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND};
21 
22static const std::vector<ge::DataType> valueType = {
23 ge::DT_INT64, ge::DT_INT32, ge::DT_FLOAT, ge::DT_FLOAT16, ge::DT_BF16, ge::DT_INT8, ge::DT_UINT8, ge::DT_BOOL,
24 ge::DT_INT64, ge::DT_INT32, ge::DT_FLOAT, ge::DT_FLOAT16, ge::DT_BF16, ge::DT_INT8, ge::DT_UINT8, ge::DT_BOOL};
25 
26static const std::vector<ge::DataType> constType = {
27 ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64,
28 ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64};
29 
30static const std::vector<ge::DataType> indicesType = {
31 ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64,
32 ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, ge::DT_INT32};
33}
34namespace ops {
35class IndexPutV2 : public OpDef {
36public:
37 explicit IndexPutV2(const char *name) : OpDef(name) {
38 this->Input("x").ParamType(REQUIRED).DataType(valueType).Format(format).UnknownShapeFormat(format);
39 this->Input("value").ParamType(REQUIRED).DataType(valueType).Format(format).UnknownShapeFormat(format);
40 this->Input("indexed_sizes")
41 .ParamType(REQUIRED)
42 .ValueDepend(OPTIONAL)
43 .DataType(constType)
44 .Format(format)
45 .UnknownShapeFormat(format);
46 this->Input("indexed_strides")
47 .ParamType(REQUIRED)
48 .DataType(constType)
49 .Format(format)
50 .UnknownShapeFormat(format);
51 this->Input("indices").ParamType(DYNAMIC).DataType(indicesType).Format(format).UnknownShapeFormat(format);
52 this->Output("x").ParamType(REQUIRED).DataType(valueType).Format(format).UnknownShapeFormat(format);
53 
54 this->Attr("accumulate").AttrType(OPTIONAL).Bool(false);
55 OpAICoreConfig aicore_config;
56 aicore_config.DynamicCompileStaticFlag(true)
57 .DynamicFormatFlag(false)
58 .DynamicRankSupportFlag(true)
59 .DynamicShapeSupportFlag(true)
60 .NeedCheckSupportFlag(false)
61 .PrecisionReduceFlag(true)
62 .ExtendCfgInfo("opFile.value", "index_put_v2_apt");
63 this->AICore().AddConfig("ascend910_95", aicore_config);
64 }
65};
66 
67OP_ADD(IndexPutV2);
68} // namespace ops
Aindex/index_put_v2/op_host/index_put_v2_infershape.cpp+30-0
@@ -0,0 +1,30 @@
1/**
2 * Copyright (c) 2025 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 index_put_v2.cc
13 * \brief
14 */
15#include "register/op_impl_registry.h"
16#include "log/log.h"
17 
18using namespace ge;
19namespace ops {
20[[maybe_unused]] static ge::graphStatus InferShapeForIndexPutV2(gert::InferShapeContext* context) {
21 auto in_shape = context->GetInputShape(0);
22 OP_CHECK_NULL_WITH_CONTEXT(context, in_shape);
23 auto out_shape = context->GetOutputShape(0);
24 OP_CHECK_NULL_WITH_CONTEXT(context, out_shape);
25 *out_shape = *in_shape;
26 return ge::GRAPH_SUCCESS;
27}
28 
29IMPL_OP_INFERSHAPE(IndexPutV2).InferShape(InferShapeForIndexPutV2);
30} // namespace ops
Aindex/index_put_v2/op_kernel/index_put_v2_apt.cpp+214-0
@@ -0,0 +1,214 @@
1/**
2 * Copyright (c) 2025 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 index_put_v2.cpp
13 * \brief Ascendc IndexPutV2 kernel
14 */
15 
16#include "../index/arch35/index.h"
17 
18using namespace Index;
19 
20extern "C" __global__ __aicore__ void index_put_v2(GM_ADDR inputX, GM_ADDR value, GM_ADDR indexedSizes,
21 GM_ADDR indexedStrides, GM_ADDR indices, GM_ADDR output,
22 GM_ADDR workspace, GM_ADDR tiling) {
23 if (workspace == nullptr) {
24 return;
25 }
26 SetSysWorkspace(workspace);
27 GM_ADDR userWS = GetUserWorkspace(workspace);
28 if (userWS == nullptr) {
29 return;
30 }
31 GET_TILING_DATA(tilingData, tiling);
32 KERNEL_TASK_TYPE_DEFAULT(KERNEL_TYPE_AIV_ONLY);
33 if (tilingData.accumulateMode) {
34 if (TILING_KEY_IS(2)) {
35 KernelIndex<half, IndexPutAdd<half>, int32_t, uint32_t> op;
36 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
37 op.Process();
38 } else if (TILING_KEY_IS(3)) {
39 KernelIndex<bfloat16_t, IndexPutAdd<bfloat16_t>, int32_t, uint32_t> op;
40 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
41 op.Process();
42 } else if (TILING_KEY_IS(4)) {
43 KernelIndex<int32_t, IndexPutAdd<int32_t>, int32_t, uint32_t> op;
44 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
45 op.Process();
46 } else if (TILING_KEY_IS(6)) {
47 KernelIndex<int32_t, IndexPutAdd<int32_t>, int32_t, uint32_t> op;
48 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
49 op.Process();
50 } else if (TILING_KEY_IS(5)) {
51 KernelIndex<float, IndexPutAdd<float>, int32_t, uint32_t> op;
52 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
53 op.Process();
54 } else if (TILING_KEY_IS(8)) {
55 KernelIndex<int64_t, IndexPutAdd<int64_t>, int32_t, uint32_t> op;
56 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
57 op.Process();
58 } else if (TILING_KEY_IS(10)) {
59 KernelIndex<int64_t, IndexPutAdd<int64_t>, int32_t, uint32_t> op;
60 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
61 op.Process();
62 } else if (TILING_KEY_IS(12)) {
63 KernelIndex<int64_t, IndexPutAdd<int64_t>, int32_t, uint32_t> op;
64 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
65 op.Process();
66 } else if (TILING_KEY_IS(102)) {
67 KernelIndex<half, IndexPutAdd<half>, int64_t, uint32_t> op;
68 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
69 op.Process();
70 } else if (TILING_KEY_IS(103)) {
71 KernelIndex<bfloat16_t, IndexPutAdd<bfloat16_t>, int64_t, uint32_t> op;
72 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
73 op.Process();
74 } else if (TILING_KEY_IS(104)) {
75 KernelIndex<int32_t, IndexPutAdd<int32_t>, int64_t, uint32_t> op;
76 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
77 op.Process();
78 } else if (TILING_KEY_IS(106)) {
79 KernelIndex<int32_t, IndexPutAdd<int32_t>, int64_t, uint32_t> op;
80 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
81 op.Process();
82 } else if (TILING_KEY_IS(105)) {
83 KernelIndex<float, IndexPutAdd<float>, int64_t, uint32_t> op;
84 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
85 op.Process();
86 } else if (TILING_KEY_IS(108)) {
87 KernelIndex<int64_t, IndexPutAdd<int64_t>, int64_t, uint32_t> op;
88 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
89 op.Process();
90 } else if (TILING_KEY_IS(110)) {
91 KernelIndex<int64_t, IndexPutAdd<int64_t>, int64_t, uint32_t> op;
92 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
93 op.Process();
94 } else if (TILING_KEY_IS(112)) {
95 KernelIndex<int64_t, IndexPutAdd<int64_t>, int64_t, uint32_t> op;
96 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
97 op.Process();
98 }
99 } else {
100 if (TILING_KEY_IS(0)) {
101 KernelIndex<uint8_t, IndexPutAssign<uint8_t>, int32_t, uint32_t> op;
102 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
103 op.Process();
104 } else if (TILING_KEY_IS(1)) {
105 KernelIndex<int8_t, IndexPutAssign<int8_t>, int32_t, uint32_t> op;
106 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
107 op.Process();
108 } else if (TILING_KEY_IS(2)) {
109 KernelIndex<half, IndexPutAssign<half>, int32_t, uint32_t> op;
110 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
111 op.Process();
112 } else if (TILING_KEY_IS(3)) {
113 KernelIndex<bfloat16_t, IndexPutAssign<bfloat16_t>, int32_t, uint32_t> op;
114 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
115 op.Process();
116 } else if (TILING_KEY_IS(4)) {
117 KernelIndex<int32_t, IndexPutAssign<int32_t>, int32_t, uint32_t> op;
118 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
119 op.Process();
120 } else if (TILING_KEY_IS(6)) {
121 KernelIndex<int32_t, IndexPutAssign<int32_t>, int32_t, uint32_t> op;
122 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
123 op.Process();
124 } else if (TILING_KEY_IS(5)) {
125 KernelIndex<float, IndexPutAssign<float>, int32_t, uint32_t> op;
126 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
127 op.Process();
128 } else if (TILING_KEY_IS(8)) {
129 KernelIndex<int64_t, IndexPutAssign<int64_t>, int32_t, uint32_t> op;
130 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
131 op.Process();
132 } else if (TILING_KEY_IS(10)) {
133 KernelIndex<int64_t, IndexPutAssign<int64_t>, int32_t, uint32_t> op;
134 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
135 op.Process();
136 } else if (TILING_KEY_IS(11)) {
137 KernelIndex<bool, IndexPutAssign<bool>, int32_t, uint32_t> op;
138 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
139 op.Process();
140 } else if (TILING_KEY_IS(12)) {
141 KernelIndex<int64_t, IndexPutAssign<int64_t>, int32_t, uint32_t> op;
142 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
143 op.Process();
144 } else if (TILING_KEY_IS(16)) {
145 KernelIndex<int4, IndexPutAssign<int4>, int32_t, uint32_t> op;
146 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
147 op.Process();
148 } else if (TILING_KEY_IS(20)) {
149 KernelIndex<int4, IndexPutAssign<int4>, int32_t, uint32_t> op;
150 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
151 op.Process();
152 } else if (TILING_KEY_IS(24)) {
153 KernelIndex<int4, IndexPutAssign<int4>, int32_t, uint32_t> op;
154 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
155 op.Process();
156 }else if (TILING_KEY_IS(100)) {
157 KernelIndex<uint8_t, IndexPutAssign<uint8_t>, int64_t, uint32_t> op;
158 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
159 op.Process();
160 } else if (TILING_KEY_IS(101)) {
161 KernelIndex<int8_t, IndexPutAssign<int8_t>, int64_t, uint32_t> op;
162 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
163 op.Process();
164 } else if (TILING_KEY_IS(102)) {
165 KernelIndex<half, IndexPutAssign<half>, int64_t, uint32_t> op;
166 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
167 op.Process();
168 } else if (TILING_KEY_IS(103)) {
169 KernelIndex<bfloat16_t, IndexPutAssign<bfloat16_t>, int64_t, uint32_t> op;
170 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
171 op.Process();
172 } else if (TILING_KEY_IS(104)) {
173 KernelIndex<int32_t, IndexPutAssign<int32_t>, int64_t, uint32_t> op;
174 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
175 op.Process();
176 } else if (TILING_KEY_IS(106)) {
177 KernelIndex<int32_t, IndexPutAssign<int32_t>, int64_t, uint32_t> op;
178 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
179 op.Process();
180 } else if (TILING_KEY_IS(105)) {
181 KernelIndex<float, IndexPutAssign<float>, int64_t, uint32_t> op;
182 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
183 op.Process();
184 } else if (TILING_KEY_IS(108)) {
185 KernelIndex<int64_t, IndexPutAssign<int64_t>, int64_t, uint32_t> op;
186 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
187 op.Process();
188 } else if (TILING_KEY_IS(110)) {
189 KernelIndex<int64_t, IndexPutAssign<int64_t>, int64_t, uint32_t> op;
190 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
191 op.Process();
192 } else if (TILING_KEY_IS(111)) {
193 KernelIndex<bool, IndexPutAssign<bool>, int64_t, uint32_t> op;
194 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
195 op.Process();
196 } else if (TILING_KEY_IS(112)) {
197 KernelIndex<int64_t, IndexPutAssign<int64_t>, int64_t, uint32_t> op;
198 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
199 op.Process();
200 } else if (TILING_KEY_IS(116)) {
201 KernelIndex<int4, IndexPutAssign<int4>, int64_t, uint32_t> op;
202 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
203 op.Process();
204 } else if (TILING_KEY_IS(120)) {
205 KernelIndex<int4, IndexPutAssign<int4>, int64_t, uint32_t> op;
206 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
207 op.Process();
208 } else if (TILING_KEY_IS(124)) {
209 KernelIndex<int4, IndexPutAssign<int4>, int64_t, uint32_t> op;
210 op.Init(output, inputX, indexedSizes, indexedStrides, indices, tilingData, value);
211 op.Process();
212 }
213 }
214}
Mindex/index_put_v2/tests/CMakeLists.txt+5-8
@@ -1,18 +1,15 @@
1#1# -----------------------------------------------------------------------------------------------------------
2# Copyright (c) 2025 Huawei Technologies Co., Ltd.2# Copyright (c) 2025 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.
6# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8# See LICENSE in the root of the software repository for the full text of the License.
9#/9# -----------------------------------------------------------------------------------------------------------
10 
11message(STATUS "=== Debug: start ops.math.is_finite.tests.CMakeLists.txt ")
12file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)10file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
13message(STATUS "=== Debug: CURRENT_DIRS =${CURRENT_DIRS} ")
14foreach(SUB_DIR ${CURRENT_DIRS})11foreach(SUB_DIR ${CURRENT_DIRS})
15 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")12 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")
16 add_subdirectory(${SUB_DIR})13 add_subdirectory(${SUB_DIR})
17 endif()14 endif()
18endforeach()15endforeach()
Mindex/index_put_v2/tests/ut/CMakeLists.txt+4-7
@@ -1,16 +1,13 @@
1#1# -----------------------------------------------------------------------------------------------------------
2# Copyright (c) 2025 Huawei Technologies Co., Ltd.2# Copyright (c) 2025 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.
6# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8# See LICENSE in the root of the software repository for the full text of the License.
9#/9# -----------------------------------------------------------------------------------------------------------
10 
11# 每个目录下需要生成的可执行文件,具体参考:ops/built-in/test/CMakeLists.txt: 50~124
12file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)10file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
13message(STATUS "=== Debug: CURRENT_DIRS =${CURRENT_DIRS} ")
14foreach(SUB_DIR ${CURRENT_DIRS})11foreach(SUB_DIR ${CURRENT_DIRS})
15 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")12 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")
16 add_subdirectory(${SUB_DIR})13 add_subdirectory(${SUB_DIR})
Dindex/index_put_v2/tests/ut/graph_plugin/fusion_pass/CMakeLists.txt+0-14
@@ -1,14 +0,0 @@
1#
2# Copyright (c) 2025 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 
11message(STATUS "=== Debug: target_sources add test_*_proto.cpp: ${test_xxx_proto.cpp} ")
12if(PASS_UT OR (UT_TEST_ALL AND NOT AICPU_ONLY))
13 add_modules_llt_sources(HOSTNAME ${OPTEST_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})
14endif()
Rindex/index_fill_d/tests/ut/graph_plugin/fusion_pass/CMakeLists.txtindex/index_put_v2/tests/ut/op_api/CMakeLists.txt+8-8
@@ -1,14 +1,14 @@
1# ----------------------------------------------------------------------------1# -----------------------------------------------------------------------------------------------------------
2# Copyright (c) 2025 Huawei Technologies Co., Ltd.2# Copyright (c) 2025 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.
6# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8# See LICENSE in the root of the software repository for the full text of the License.
9# ----------------------------------------------------------------------------9# -----------------------------------------------------------------------------------------------------------
10 10 
11message(STATUS "=== Debug: target_sources add test_*_proto.cpp: ${test_xxx_proto.cpp} ")11file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
12if(PASS_UT OR (UT_TEST_ALL AND NOT AICPU_ONLY))12if(UT_TEST_ALL OR OP_API_UT)
13 add_modules_llt_sources(HOSTNAME ${OPTEST_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})13 add_modules_ut_sources(HOSTNAME ${OP_API_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})
14endif()14endif()
Rindex/index_put_v2/tests/ut/op_host/test_aclnn_index_put_impl.cppindex/index_put_v2/tests/ut/op_api/test_aclnn_index_put_impl.cpp+3-1文件内容审核中,请稍后刷新重试
Mindex/index_put_v2/tests/ut/op_host/CMakeLists.txt+4-7
@@ -1,18 +1,15 @@
1# ----------------------------------------------------------------------------1# -----------------------------------------------------------------------------------------------------------
2# Copyright (c) 2025 Huawei Technologies Co., Ltd.2# Copyright (c) 2025 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.
6# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8# See LICENSE in the root of the software repository for the full text of the License.
9# ----------------------------------------------------------------------------9# -----------------------------------------------------------------------------------------------------------
10 10 
11file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)11file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
12if(UT_TEST_ALL OR OP_HOST_UT)12if(UT_TEST_ALL OR OP_HOST_UT)
13 add_modules_ut_sources(HOSTNAME ${OP_TILING_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})13 add_modules_ut_sources(HOSTNAME ${OP_TILING_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})
14 add_modules_ut_sources(HOSTNAME ${OP_INFERSHAPE_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})14 add_modules_ut_sources(HOSTNAME ${OP_INFERSHAPE_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})
15endif()
16if(UT_TEST_ALL OR OP_API_UT)
17 add_modules_ut_sources(HOSTNAME ${OP_API_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})
18endif()15endif()
Aindex/index_put_v2/tests/ut/op_host/test_index_put_v2_infershape.cpp+95-0
@@ -0,0 +1,95 @@
1/**
2 * Copyright (c) 2025 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_index_put_v2_infershape.cpp
13 * \brief
14 */
15 
16#include "ut_op_util.h"
17#include "infershape_test_util.h"
18#include <iostream>
19#include "exe_graph/runtime/storage_format.h"
20#include "exe_graph/runtime/storage_shape.h"
21#include <gtest/gtest.h>
22#include "kernel_run_context_facker.h"
23#include "register/op_impl_registry.h"
24#include "log/log.h"
25#include "platform/platform_info.h"
26#include "../../../op_graph/index_put_v2_proto.h"
27#include "ut_op_common.h"
28 
29class IndexPutV2 : public testing::Test {
30protected:
31 static void SetUpTestCase()
32 {
33 std::cout << "IndexPutV2 SetUp" << std::endl;
34 }
35 
36 static void TearDownTestCase()
37 {
38 std::cout << "IndexPutV2 TearDown" << std::endl;
39 }
40};
41 
42TEST_F(IndexPutV2, IndexPutV2_infershape_case_1)
43{
44 ge::op::IndexPutV2 op;
45 op.UpdateInputDesc("x", create_desc({1000, 1000}, ge::DT_INT64));
46 op.UpdateInputDesc("value", create_desc({1, 1}, ge::DT_INT64));
47 op.UpdateInputDesc("indexed_sizes", create_desc({1, 1}, ge::DT_INT64));
48 op.UpdateInputDesc("indexed_strides", create_desc({1, 1}, ge::DT_INT64));
49 op.UpdateInputDesc("indices", create_desc({1, 1}, ge::DT_INT64));
50 op.SetAttr("accumulate", false);
51 Runtime2TestParam param{{"accumulate"}, {}, {}};
52 EXPECT_EQ(InferShapeTest(op, param), ge::GRAPH_SUCCESS);
53 auto outputY = op.GetOutputDesc(0);
54 std::vector<int64_t> expectedYShape = {1000, 1000};
55 EXPECT_EQ(outputY.GetShape().GetDims(), expectedYShape);
56}
57 
58TEST_F(IndexPutV2, IndexPutV2_InferDtype_case_1)
59{
60 ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl("IndexPutV2"), nullptr);
61 auto data_type_func = gert::OpImplRegistry::GetInstance().GetOpImpl("IndexPutV2")->infer_datatype;
62 
63 if (data_type_func != nullptr) {
64 ge::DataType input_x_ref = ge::DT_INT64;
65 ge::DataType input_vaule_ref = ge::DT_INT64;
66 ge::DataType input_indexed_sizes_ref = ge::DT_INT64;
67 ge::DataType input_indexed_strides_ref = ge::DT_INT64;
68 ge::DataType input_indices_ref = ge::DT_INT64;
69 ge::DataType output_y_ref = ge::DT_INT64;
70 auto context_holder = gert::InferDataTypeContextFaker()
71 .IrInputNum(5)
72 .NodeIoNum(5, 1)
73 .NodeInputTd(0, ge::DT_INT64, ge::FORMAT_ND, ge::FORMAT_ND)
74 .NodeInputTd(1, ge::DT_INT64, ge::FORMAT_ND, ge::FORMAT_ND)
75 .NodeInputTd(2, ge::DT_INT64, ge::FORMAT_ND, ge::FORMAT_ND)
76 .NodeInputTd(3, ge::DT_INT64, ge::FORMAT_ND, ge::FORMAT_ND)
77 .NodeInputTd(4, ge::DT_INT64, ge::FORMAT_ND, ge::FORMAT_ND)
78 .NodeOutputTd(0, ge::DT_INT64, ge::FORMAT_ND, ge::FORMAT_ND)
79 .NodeAttrs(
80 {{"accumulate", Ops::NN::AnyValue::CreateFrom<bool>(false)}})
81 .InputDataTypes({&input_x_ref, &input_vaule_ref, &input_indexed_sizes_ref, &input_indexed_strides_ref, &input_indices_ref})
82 .OutputDataTypes({&output_y_ref})
83 .Build();
84 auto context = context_holder.GetContext<gert::InferDataTypeContext>();
85 EXPECT_EQ(data_type_func(context), ge::GRAPH_SUCCESS);
86 ASSERT_NE(context, nullptr);
87 
88 EXPECT_EQ(context->GetInputDataType(0), input_x_ref);
89 EXPECT_EQ(context->GetInputDataType(1), input_vaule_ref);
90 EXPECT_EQ(context->GetInputDataType(2), input_indexed_sizes_ref);
91 EXPECT_EQ(context->GetInputDataType(3), input_indexed_strides_ref);
92 EXPECT_EQ(context->GetInputDataType(4), input_indices_ref);
93 EXPECT_EQ(context->GetOutputDataType(0), output_y_ref);
94 }
95}
Aindex/index_put_v2/tests/ut/op_host/test_index_put_v2_tiling.cpp+163-0文件内容审核中,请稍后刷新重试
Mindex/index_put_with_sort/op_host/op_api/index_put_with_sort.cpp+1-0
@@ -12,6 +12,7 @@
12 * \file index_put_with_sort.cpp12 * \file index_put_with_sort.cpp
13 * \brief13 * \brief
14 */14 */
15 
15#include "index_put_with_sort.h"16#include "index_put_with_sort.h"
16#include "opdev/data_type_utils.h"17#include "opdev/data_type_utils.h"
17#include "opdev/format_utils.h"18#include "opdev/format_utils.h"
Mindex/index_put_with_sort_v2/op_host/op_api/index_put_with_sort_v2.cpp+1-0
@@ -12,6 +12,7 @@
12 * \file index_put_with_sort_v2.cpp12 * \file index_put_with_sort_v2.cpp
13 * \brief13 * \brief
14 */14 */
15 
15#include "index_put_with_sort_v2.h"16#include "index_put_with_sort_v2.h"
16#include "opdev/data_type_utils.h"17#include "opdev/data_type_utils.h"
17#include "opdev/format_utils.h"18#include "opdev/format_utils.h"
Mindex/linear_index_v2/op_host/op_api/linear_index_v2.cpp+1-0
@@ -12,6 +12,7 @@
12 * \file linear_index_v2.cpp12 * \file linear_index_v2.cpp
13 * \brief13 * \brief
14 */14 */
15 
15#include "linear_index_v2.h"16#include "linear_index_v2.h"
16#include "opdev/make_op_executor.h"17#include "opdev/make_op_executor.h"
17#include "opdev/op_dfx.h"18#include "opdev/op_dfx.h"
Rindex/index_put_v2/op_host/CMakeLists.txtquant/grouped_dynamic_mx_quant/CMakeLists.txt+9-5文件内容审核中,请稍后刷新重试
Aquant/grouped_dynamic_mx_quant/README.md+114-0
@@ -0,0 +1,114 @@
1# GroupedDynamicMxQuant
2 
3## 产品支持情况
4 
5| 产品 | 是否支持 |
6| :----------------------------------------------------------- | :------: |
7| <term>Ascend 950PR/Ascend 950DT</term> | √ |
8| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | × |
9| <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term> | × |
10 
11## 功能说明
12 
13- 接口功能:根据传入的分组索引的起始值,对传入的数据进行分组的float8的动态量化。
14 
15- 计算公式:
16 - 将输入x在第0维上先按照groupIndex进行分组,每个group内按k = blocksize个数分组,一组k个数 {{x<sub>i</sub>}<sub>i=1</sub><sup>k</sup>} 计算出这组数对应的量化尺度mxscale_pre, {mxscale_pre, {P<sub>i</sub>}<sub>i=1</sub><sup>k</sup>}, 计算公式为下面公式(1)(2)。
17 $$
18 shared\_exp = floor(log_2(max_i(|V_i|))) - emax \tag{1}
19 $$
20 $$
21 mxscale\_pre = 2^{shared\_exp} \tag{2}
22 $$
23 - 这组数每一个除以mxscale,根据round_mode转换到对应的dst_type,得到量化结果y, 计算公式为下面公式(3)。
24 $$
25 P_i = cast\_to\_dst\_type(V_i/mxscale, round\_mode), \space i\space from\space 1\space to\space blocksize \tag{3}
26 $$
27
28 ​ 量化后的P<sub>i</sub>按对应的x<sub>i</sub>的位置组成输出y,mxscale_pre按对应的groupIndex分组,分组内第一个维度pad为偶数,组成输出mxscale。
29
30 - emax: 对应数据类型的最大正则数的指数位。
31
32 | DataType | emax |
33 | :-----------: | :--: |
34 | FLOAT8_E4M3FN | 8 |
35 | FLOAT8_E5M2 | 15 |
36 
37 
38## 参数说明
39 
40<table style="undefined;table-layout: fixed; width: 980px"><colgroup>
41 <col style="width: 100px">
42 <col style="width: 150px">
43 <col style="width: 280px">
44 <col style="width: 330px">
45 <col style="width: 120px">
46 </colgroup>
47 <thead>
48 <tr>
49 <th>参数名</th>
50 <th>输入/输出</th>
51 <th>描述</th>
52 <th>数据类型</th>
53 <th>数据格式</th>
54 </tr></thead>
55 <tbody>
56 <tr>
57 <td>x</td>
58 <td>输入</td>
59 <td>Device侧的aclTensor,计算公式中的输入x。shape仅支持2维。支持非连续的Tensor,支持空Tensor。</td>
60 <td>FLOAT16、BFLOAT16</td>
61 <td>ND</td>
62 </tr>
63 <tr>
64 <td>groupIndex</td>
65 <td>输入</td>
66 <td>Device侧的aclTensor,量化分组的起始索引。shape仅支持1维。支持非连续的Tensor,支持空Tensor。</td>
67 <td>INT32</td>
68 <td>ND</td>
69 </tr>
70 <tr>
71 <td>roundMode</td>
72 <td>输入</td>
73 <td>host侧的string,公式中的round_mode,数据转换的模式,仅支持"rint"模式。</td>
74 <td>-</td>
75 <td>-</td>
76 </tr>
77 <tr>
78 <td>dstType</td>
79 <td>输入</td>
80 <td>host侧的int64_t,公式中的dst_type,指定数据转换后y的类型,输入范围为{35, 36},分别对应输出y的数据类型为{35: FLOAT8_E5M2, 36: FLOAT8_E4M3FN}。</td>
81 <td>-</td>
82 <td>-</td>
83 </tr>
84 <tr>
85 <td>blocksize</td>
86 <td>输入</td>
87 <td>host侧的int64_t,公式中的blocksize,指定每次量化的元素个数,仅支持32。</td>
88 <td>-</td>
89 <td>-</td>
90 </tr>
91 <tr>
92 <td>y</td>
93 <td>输出</td>
94 <td>Device侧的aclTensor,公式中的输出y,输入x量化后的对应结果。需与dstType对应,shape仅支持2维,支持空Tensor,Shape和输入x一致。</td>
95 <td>FLOAT8_E4M3FN、FLOAT8_E5M2</td>
96 <td>ND</td>
97 </tr>
98 <tr>
99 <td>mxscale</td>
100 <td>输出</td>
101 <td>Device侧的aclTensor,公式中的mxscale_pre组成的输出mxscale,每个分组对应的量化尺度。需与dstType对应,shape仅支持3维,支持空Tensor,Shape和输入x一致。假设x的shape为 $[m,n]$,groupedIndex的shape为 $[g]$,则mxscale的shape为 $[(m/(blocksize * 2)+g), n, 2]$</td>
102 <td>FLOAT8_E8M0</td>
103 <td>ND</td>
104 </tr>
105 </tbody></table>
106 
107## 约束说明
108 
109
110## 调用说明
111 
112| 调用方式 | 调用样例 | 说明 |
113|--------------|------------------------------------------------------------------------|--------------------------------------------------------------|
114| aclnn调用 | [test_aclnn_grouped_dynamic_mx_quant](./examples/test_aclnn_grouped_dynamic_mx_quant.cpp) | 通过[aclnnGroupedDynamicMxQuant](./docs/aclnnGroupedDynamicMxQuant.md)接口方式调用GroupedDynamicMxQuant算子。 |
Aquant/grouped_dynamic_mx_quant/docs/aclnnGroupedDynamicMxQuant.md+283-0
@@ -0,0 +1,283 @@
1# aclnnGroupedDynamicMxQuant
2 
3## 产品支持情况
4 
5| 产品 | 是否支持 |
6| :----------------------------------------------------------- | :------: |
7| Ascend 950PR/Ascend 950DT</term> | √ |
8| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | × |
9| <term>Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件</term> | × |
10 
11## 功能说明
12 
13- 接口功能:根据传入的分组索引的起始值,对传入的数据进行分组的float8的动态量化。
14 
15- 计算公式:
16 - 将输入x在第0维上先按照groupIndex进行分组,每个group内按k = blocksize个数分组,一组k个数 {{x<sub>i</sub>}<sub>i=1</sub><sup>k</sup>} 计算出这组数对应的量化尺度mxscale_pre, {mxscale_pre, {P<sub>i</sub>}<sub>i=1</sub><sup>k</sup>}, 计算公式为下面公式(1)(2)。
17 $$
18 shared\_exp = floor(log_2(max_i(|V_i|))) - emax \tag{1}
19 $$
20 $$
21 mxscale\_pre = 2^{shared\_exp} \tag{2}
22 $$
23 - 这组数每一个除以mxscale,根据round_mode转换到对应的dst_type,得到量化结果y, 计算公式为下面公式(3)。
24 $$
25 P_i = cast\_to\_dst\_type(V_i/mxscale, round\_mode), \space i\space from\space 1\space to\space blocksize \tag{3}
26 $$
27
28 ​ 量化后的P<sub>i</sub>按对应的x<sub>i</sub>的位置组成输出y,mxscale_pre按对应的groupIndex分组,分组内第一个维度pad为偶数,组成输出mxscale。
29
30 - emax: 对应数据类型的最大正则数的指数位。
31
32 | DataType | emax |
33 | :-----------: | :--: |
34 | FLOAT8_E4M3FN | 8 |
35 | FLOAT8_E5M2 | 15 |
36 
37## 函数原型
38每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用“aclnnGroupedDynamicMxQuantGetWorkspaceSize”接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用“aclnnGroupedDynamicMxQuant”接口执行计算。
39 
40- `aclnnStatus aclnnGroupedDynamicMxQuantGetWorkspaceSize(const aclTensor* x, const aclTensor* groupIndex, const char* roundMode, int64_t dstType, int64_t blocksize, aclTensor* y, aclTensor* mxscale, uint64_t* workspaceSize, aclOpExecutor** executor)`
41 
42- `aclnnStatus aclnnGroupedDynamicMxQuant(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream)`
43 
44## aclnnGroupedDynamicMxQuantGetWorkspaceSize
45 
46- **参数说明:**
47
48 - x(aclTensor*,计算输入):Device侧的aclTensor,计算公式中的输入x。数据类型支持FLOAT16、BFLOAT16,shape仅支持2维,支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),支持空Tensor,[数据格式](../../../docs/zh/context/数据格式.md)支持ND格式。
49 - groupIndex(aclTensor*,计算输入):Device侧的aclTensor,量化分组的起始索引。数据类型支持INT32,shape仅支持1维,支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),不支持空Tensor,[数据格式](../../../docs/zh/context/数据格式.md)支持ND格式。索引要求大于等于0,且非递减,并且最后一个数需要与x的第一个维度大小相等。
50 - roundMode(char*,计算输入):host侧的string,公式中的round_mode,数据转换的模式,仅支持"rint"模式。
51 - dstType(int64_t,计算输入):host侧的int64_t,公式中的dst_type,指定数据转换后y的类型,输入范围为{35, 36},分别对应输出y的数据类型为{35: FLOAT8_E5M2, 36: FLOAT8_E4M3FN}。
52 - blocksize(int64_t,计算输入):host侧的int64_t,公式中的blocksize,指定每次量化的元素个数,仅支持32。
53 - y(aclTensor*,计算输出):Device侧的aclTensor,公式中的输出y,输入x量化后的对应结果。数据类型支持FLOAT8_E4M3FN、FLOAT8_E5M2,需与dstType对应,shape仅支持2维,支持空Tensor,[数据格式](../../../docs/zh/context/数据格式.md)支持ND格式。Shape和输入x一致。
54 - mxscale(aclTensor*,计算输出):Device侧的aclTensor,公式中的mxscale_pre组成的输出mxscale,每个分组对应的量化尺度。数据类型支持FLOAT8_E8M0,shape仅支持3维度,支持空Tensor,[数据格式](../../../docs/zh/context/数据格式.md)支持ND格式。假设x的shape为 $[m,n]$,groupedIndex的shape为 $[g]$,则mxscale的shape为 $[(m/(blocksize * 2)+g), n, 2]$。
55 - workspaceSize(uint64_t*,出参):返回需要在Device侧申请的workspace大小。
56 - executor(aclOpExecutor**,出参):返回op执行器,包含了算子计算流程。
57
58- **返回值:**
59 
60 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
61 
62 ```
63 第一段接口完成入参校验,出现以下场景时报错:
64 返回161001(ACLNN_ERR_PARAM_NULLPTR):1. 传入的x、groupIndex、y和mxscale是空指针。
65 2. 传入的roundMode是空指针。
66 返回161002(ACLNN_ERR_PARAM_INVALID):1. x、groupIndex、y、mxscale的数据类型不在支持的范围之内。
67 2. x、y和mxscale的shape不满足校验条件。
68 3. x、groupIndex、y和mxscale的维度不在支持的范围之内。
69 4. roundMode、dstType、blocksize不符合当前支持的值。
70 5. mxscale不支持非连续的Tensor。
71 返回361001(ACLNN_ERR_RUNTIME_ERROR):当前平台不在支持的平台范围内。
72 ```
73 
74## aclnnGroupedDynamicMxQuant
75 
76- **参数说明:**
77 - workspace(void*, 入参):在Device侧申请的workspace内存地址。
78 - workspaceSize(uint64_t, 入参):在Device侧申请的workspace大小,由第一段接口aclnnGroupedDynamicMxQuantGetWorkspaceSize获取。
79 - executor(aclOpExecutor*, 入参):op执行器,包含了算子计算流程。
80 - stream(aclrtStream, 入参):指定执行任务的Stream。
81 
82- **返回值:**
83 
84 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
85 
86## 约束说明
87 
88- 确定性计算:
89 - aclnnGroupedDynamicMxQuant默认确定性实现。
90 
91## 调用示例
92示例代码如下,仅供参考,具体编译和执行过程请参考[编译与运行样例](../../../docs/zh/context/编译与运行样例.md)。
93
94```Cpp
95#include <iostream>
96#include <memory>
97#include <vector>
98 
99#include "acl/acl.h"
100#include "aclnnop/aclnn_grouped_dynamic_mx_quant.h"
101 
102#define CHECK_RET(cond, return_expr) \
103 do { \
104 if (!(cond)) { \
105 return_expr; \
106 } \
107 } while (0)
108 
109#define CHECK_FREE_RET(cond, return_expr) \
110 do { \
111 if (!(cond)) { \
112 Finalize(deviceId, stream); \
113 return_expr; \
114 } \
115 } while (0)
116 
117#define LOG_PRINT(message, ...) \
118 do { \
119 printf(message, ##__VA_ARGS__); \
120 } while (0)
121 
122int64_t GetShapeSize(const std::vector<int64_t>& shape)
123{
124 int64_t shapeSize = 1;
125 for (auto i : shape) {
126 shapeSize *= i;
127 }
128 return shapeSize;
129}
130 
131int Init(int32_t deviceId, aclrtStream* stream)
132{
133 // 固定写法,资源初始化
134 auto ret = aclInit(nullptr);
135 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);
136 ret = aclrtSetDevice(deviceId);
137 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);
138 ret = aclrtCreateStream(stream);
139 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);
140 return 0;
141}
142 
143template <typename T>
144int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, aclDataType dataType, aclTensor** tensor)
145{
146 auto size = GetShapeSize(shape) * sizeof(T);
147 // 调用aclrtMalloc申请device侧内存
148 auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);
149 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);
150 // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上
151 ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);
152 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);
153 
154 // 计算连续tensor的strides
155 std::vector<int64_t> strides(shape.size(), 1);
156 for (int64_t i = shape.size() - 2; i >= 0; i--) {
157 strides[i] = shape[i + 1] * strides[i + 1];
158 }
159 
160 // 调用aclCreateTensor接口创建aclTensor
161 *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND,
162 shape.data(), shape.size(), *deviceAddr);
163 return 0;
164}
165 
166void Finalize(int32_t deviceId, aclrtStream stream)
167{
168 aclrtDestroyStream(stream);
169 aclrtResetDevice(deviceId);
170 aclFinalize();
171}
172 
173int aclnnGroupedDynamicMxQuantTest(int32_t deviceId, aclrtStream& stream)
174{
175 auto ret = Init(deviceId, &stream);
176 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);
177 
178 // 2. 构造输入与输出,需要根据API的接口自定义构造
179 std::vector<int64_t> xShape = {8, 1};
180 std::vector<int64_t> groupedIndexShape = {2};
181 std::vector<int64_t> yOutShape = {8, 1};
182 std::vector<int64_t> mxscaleOutShape = {2, 1, 2};
183 void* xDeviceAddr = nullptr;
184 void* groupedIndexDeviceAddr = nullptr;
185 void* yOutDeviceAddr = nullptr;
186 void* mxscaleOutDeviceAddr = nullptr;
187 aclTensor* x = nullptr;
188 aclTensor* groupedIndex = nullptr;
189 aclTensor* yOut = nullptr;
190 aclTensor* mxscaleOut = nullptr;
191 //对应BF16的值(0, 8, 64, 512)
192 std::vector<uint16_t> xHostData = {{0}, {16640}, {17024}, {17408}, {0}, {16640}, {17024}, {17408}};
193
194 std::vector<uint32_t> groupedIndexHostData = {4,8};
195 //对应float8_e4m3的值(0, 4, 32, 256)
196 std::vector<uint8_t> yOutHostData = {{0}, {72}, {96}, {120}, {0}, {72}, {96}, {120}};
197 //对应float8_e8m0的值(2)
198 std::vector<std::vector<uint8_t>> mxscaleOutHostData = {{{128, 0}}, {{128, 0}}};
199 const char* roundModeOptional = "rint";
200 int64_t dstType = 36;
201 int64_t blocksize = 32;
202 // 创建x aclTensor
203 ret = CreateAclTensor(xHostData, xShape, &xDeviceAddr, aclDataType::ACL_BF16, &x);
204 std::unique_ptr<aclTensor, aclnnStatus (*)(const aclTensor*)> xTensorPtr(x, aclDestroyTensor);
205 std::unique_ptr<void, aclError (*)(void*)> xDeviceAddrPtr(xDeviceAddr, aclrtFree);
206 CHECK_RET(ret == ACL_SUCCESS, return ret);
207 // 创建groudedIndex aclTensor
208 ret = CreateAclTensor(groupedIndexHostData, groupedIndexShape, &groupedIndexDeviceAddr, aclDataType::ACL_INT32, &groupedIndex);
209 std::unique_ptr<aclTensor, aclnnStatus (*)(const aclTensor*)> groupedIndexTensorPtr(groupedIndex, aclDestroyTensor);
210 std::unique_ptr<void, aclError (*)(void*)> groupedIndexDeviceAddrPtr(groupedIndexDeviceAddr, aclrtFree);
211 CHECK_RET(ret == ACL_SUCCESS, return ret);
212 // 创建yOut aclTensor
213 ret = CreateAclTensor(yOutHostData, yOutShape, &yOutDeviceAddr, aclDataType::ACL_FLOAT8_E4M3FN, &yOut);
214 std::unique_ptr<aclTensor, aclnnStatus (*)(const aclTensor*)> yOutTensorPtr(yOut, aclDestroyTensor);
215 std::unique_ptr<void, aclError (*)(void*)> yOutDeviceAddrPtr(yOutDeviceAddr, aclrtFree);
216 CHECK_RET(ret == ACL_SUCCESS, return ret);
217 // 创建mxscaleOut aclTensor
218 ret = CreateAclTensor(mxscaleOutHostData, mxscaleOutShape, &mxscaleOutDeviceAddr, aclDataType::ACL_FLOAT8_E8M0, &mxscaleOut);
219 std::unique_ptr<aclTensor, aclnnStatus (*)(const aclTensor*)> mxscaleOutTensorPtr(mxscaleOut, aclDestroyTensor);
220 std::unique_ptr<void, aclError (*)(void*)> mxscaleOutDeviceAddrPtr(mxscaleOutDeviceAddr, aclrtFree);
221 CHECK_RET(ret == ACL_SUCCESS, return ret);
222
223 // 调用CANN算子库API,需要修改为具体的Api名称
224 uint64_t workspaceSize = 0;
225 aclOpExecutor* executor;
226 
227 // 调用aclnnDynamicMxQuant第一段接口
228 ret = aclnnGroupedDynamicMxQuantGetWorkspaceSize(x, groupedIndex, roundModeOptional, dstType, blocksize, yOut, mxscaleOut, &workspaceSize, &executor);
229 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnGroupedDynamicMxQuantGetWorkspaceSize failed. ERROR: %d\n", ret);
230 return ret);
231 // 根据第一段接口计算出的workspaceSize申请device内存
232 void* workspaceAddr = nullptr;
233 std::unique_ptr<void, aclError (*)(void*)> workspaceAddrPtr(nullptr, aclrtFree);
234 if (workspaceSize > 0) {
235 ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
236 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
237 workspaceAddrPtr.reset(workspaceAddr);
238 }
239 // 调用aclnnDynamicMxQuant第二段接口
240 ret = aclnnGroupedDynamicMxQuant(workspaceAddr, workspaceSize, executor, stream);
241 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnDynamicMxQuant failed. ERROR: %d\n", ret); return ret);
242 
243 //(固定写法)同步等待任务执行结束
244 ret = aclrtSynchronizeStream(stream);
245 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
246 
247 // 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改
248 auto size = GetShapeSize(yOutShape);
249 std::vector<uint8_t> yOutData(
250 size, 0); // C语言中无法直接打印fp4的数据,需要用uint8读出来,自行通过二进制转成fp4
251 ret = aclrtMemcpy(yOutData.data(), yOutData.size() * sizeof(yOutData[0]), yOutDeviceAddr,
252 size * sizeof(yOutData[0]), ACL_MEMCPY_DEVICE_TO_HOST);
253 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy yOut from device to host failed. ERROR: %d\n", ret);
254 return ret);
255 for (int64_t i = 0; i < size; i++) {
256 LOG_PRINT("y[%ld] is: %d\n", i, yOutData[i]);
257 }
258 size = GetShapeSize(mxscaleOutShape);
259 std::vector<uint8_t> mxscaleOutData(
260 size, 0); // C语言中无法直接打印fp8的数据,需要用uint8读出来,自行通过二进制转成fp8
261 ret = aclrtMemcpy(mxscaleOutData.data(), mxscaleOutData.size() * sizeof(mxscaleOutData[0]), mxscaleOutDeviceAddr,
262 size * sizeof(mxscaleOutData[0]), ACL_MEMCPY_DEVICE_TO_HOST);
263 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy mxscaleOut from device to host failed. ERROR: %d\n", ret);
264 return ret);
265 for (int64_t i = 0; i < size; i++) {
266 LOG_PRINT("mxscaleOut[%ld] is: %d\n", i, mxscaleOutData[i]);
267 }
268 return ACL_SUCCESS;
269}
270 
271int main()
272{
273 // 1. (固定写法)device/stream初始化,参考acl API手册
274 // 根据自己的实际device填写deviceId
275 int32_t deviceId = 0;
276 aclrtStream stream;
277 auto ret = aclnnGroupedDynamicMxQuantTest(deviceId, stream);
278 CHECK_FREE_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnGroupedDynamicMxQuantTest failed. ERROR: %d\n", ret); return ret);
279 
280 Finalize(deviceId, stream);
281 return 0;
282}
283```
Aquant/grouped_dynamic_mx_quant/examples/arch35/test_aclnn_grouped_dynamic_mx_quant.cpp+203-0
@@ -0,0 +1,203 @@
1/**
2 * Copyright (c) 2025 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_aclnn_grouped_dynamic_mx_quant.cpp
13 * \brief
14 */
15 
16#include <iostream>
17#include <memory>
18#include <vector>
19 
20#include "acl/acl.h"
21#include "aclnnop/aclnn_grouped_dynamic_mx_quant.h"
22 
23#define CHECK_RET(cond, return_expr) \
24 do { \
25 if (!(cond)) { \
26 return_expr; \
27 } \
28 } while (0)
29 
30#define CHECK_FREE_RET(cond, return_expr) \
31 do { \
32 if (!(cond)) { \
33 Finalize(deviceId, stream); \
34 return_expr; \
35 } \
36 } while (0)
37 
38#define LOG_PRINT(message, ...) \
39 do { \
40 printf(message, ##__VA_ARGS__); \
41 } while (0)
42 
43int64_t GetShapeSize(const std::vector<int64_t>& shape)
44{
45 int64_t shapeSize = 1;
46 for (auto i : shape) {
47 shapeSize *= i;
48 }
49 return shapeSize;
50}
51 
52int Init(int32_t deviceId, aclrtStream* stream)
53{
54 // 固定写法,资源初始化
55 auto ret = aclInit(nullptr);
56 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);
57 ret = aclrtSetDevice(deviceId);
58 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);
59 ret = aclrtCreateStream(stream);
60 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);
61 return 0;
62}
63 
64template <typename T>
65int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, aclDataType dataType, aclTensor** tensor)
66{
67 auto size = GetShapeSize(shape) * sizeof(T);
68 // 调用aclrtMalloc申请device侧内存
69 auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);
70 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);
71 // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上
72 ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);
73 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);
74 
75 // 计算连续tensor的strides
76 std::vector<int64_t> strides(shape.size(), 1);
77 for (int64_t i = shape.size() - 2; i >= 0; i--) {
78 strides[i] = shape[i + 1] * strides[i + 1];
79 }
80 
81 // 调用aclCreateTensor接口创建aclTensor
82 *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND,
83 shape.data(), shape.size(), *deviceAddr);
84 return 0;
85}
86 
87void Finalize(int32_t deviceId, aclrtStream stream)
88{
89 aclrtDestroyStream(stream);
90 aclrtResetDevice(deviceId);
91 aclFinalize();
92}
93 
94int aclnnGroupedDynamicMxQuantTest(int32_t deviceId, aclrtStream& stream)
95{
96 auto ret = Init(deviceId, &stream);
97 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);
98 
99 // 2. 构造输入与输出,需要根据API的接口自定义构造
100 std::vector<int64_t> xShape = {8, 1};
101 std::vector<int64_t> groupedIndexShape = {2};
102 std::vector<int64_t> yOutShape = {8, 1};
103 std::vector<int64_t> mxscaleOutShape = {2, 1, 2};
104 void* xDeviceAddr = nullptr;
105 void* groupedIndexDeviceAddr = nullptr;
106 void* yOutDeviceAddr = nullptr;
107 void* mxscaleOutDeviceAddr = nullptr;
108 aclTensor* x = nullptr;
109 aclTensor* groupedIndex = nullptr;
110 aclTensor* yOut = nullptr;
111 aclTensor* mxscaleOut = nullptr;
112 //对应BF16的值(0, 8, 64, 512)
113 std::vector<uint16_t> xHostData = {{0}, {16640}, {17024}, {17408}, {0}, {16640}, {17024}, {17408}};
114
115 std::vector<uint32_t> groupedIndexHostData = {4,8};
116 //对应float8_e4m3的值(0, 4, 32, 256)
117 std::vector<uint8_t> yOutHostData = {{0}, {72}, {96}, {120}, {0}, {72}, {96}, {120}};
118 //对应float8_e8m0的值(2)
119 std::vector<std::vector<uint8_t>> mxscaleOutHostData = {{{128, 0}}, {{128, 0}}};
120 const char* roundModeOptional = "rint";
121 int64_t dstType = 36;
122 int64_t blocksize = 32;
123 // 创建x aclTensor
124 ret = CreateAclTensor(xHostData, xShape, &xDeviceAddr, aclDataType::ACL_BF16, &x);
125 std::unique_ptr<aclTensor, aclnnStatus (*)(const aclTensor*)> xTensorPtr(x, aclDestroyTensor);
126 std::unique_ptr<void, aclError (*)(void*)> xDeviceAddrPtr(xDeviceAddr, aclrtFree);
127 CHECK_RET(ret == ACL_SUCCESS, return ret);
128 // 创建groudedIndex aclTensor
129 ret = CreateAclTensor(groupedIndexHostData, groupedIndexShape, &groupedIndexDeviceAddr, aclDataType::ACL_INT32, &groupedIndex);
130 std::unique_ptr<aclTensor, aclnnStatus (*)(const aclTensor*)> groupedIndexTensorPtr(groupedIndex, aclDestroyTensor);
131 std::unique_ptr<void, aclError (*)(void*)> groupedIndexDeviceAddrPtr(groupedIndexDeviceAddr, aclrtFree);
132 CHECK_RET(ret == ACL_SUCCESS, return ret);
133 // 创建yOut aclTensor
134 ret = CreateAclTensor(yOutHostData, yOutShape, &yOutDeviceAddr, aclDataType::ACL_FLOAT8_E4M3FN, &yOut);
135 std::unique_ptr<aclTensor, aclnnStatus (*)(const aclTensor*)> yOutTensorPtr(yOut, aclDestroyTensor);
136 std::unique_ptr<void, aclError (*)(void*)> yOutDeviceAddrPtr(yOutDeviceAddr, aclrtFree);
137 CHECK_RET(ret == ACL_SUCCESS, return ret);
138 // 创建mxscaleOut aclTensor
139 ret = CreateAclTensor(mxscaleOutHostData, mxscaleOutShape, &mxscaleOutDeviceAddr, aclDataType::ACL_FLOAT8_E8M0, &mxscaleOut);
140 std::unique_ptr<aclTensor, aclnnStatus (*)(const aclTensor*)> mxscaleOutTensorPtr(mxscaleOut, aclDestroyTensor);
141 std::unique_ptr<void, aclError (*)(void*)> mxscaleOutDeviceAddrPtr(mxscaleOutDeviceAddr, aclrtFree);
142 CHECK_RET(ret == ACL_SUCCESS, return ret);
143
144 // 调用CANN算子库API,需要修改为具体的Api名称
145 uint64_t workspaceSize = 0;
146 aclOpExecutor* executor;
147 
148 // 调用aclnnDynamicMxQuant第一段接口
149 ret = aclnnGroupedDynamicMxQuantGetWorkspaceSize(x, groupedIndex, roundModeOptional, dstType, blocksize, yOut, mxscaleOut, &workspaceSize, &executor);
150 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnGroupedDynamicMxQuantGetWorkspaceSize failed. ERROR: %d\n", ret);
151 return ret);
152 // 根据第一段接口计算出的workspaceSize申请device内存
153 void* workspaceAddr = nullptr;
154 std::unique_ptr<void, aclError (*)(void*)> workspaceAddrPtr(nullptr, aclrtFree);
155 if (workspaceSize > 0) {
156 ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
157 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
158 workspaceAddrPtr.reset(workspaceAddr);
159 }
160 // 调用aclnnDynamicMxQuant第二段接口
161 ret = aclnnGroupedDynamicMxQuant(workspaceAddr, workspaceSize, executor, stream);
162 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnDynamicMxQuant failed. ERROR: %d\n", ret); return ret);
163 
164 //(固定写法)同步等待任务执行结束
165 ret = aclrtSynchronizeStream(stream);
166 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
167 
168 // 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改
169 auto size = GetShapeSize(yOutShape);
170 std::vector<uint8_t> yOutData(
171 size, 0); // C语言中无法直接打印fp4的数据,需要用uint8读出来,自行通过二进制转成fp4
172 ret = aclrtMemcpy(yOutData.data(), yOutData.size() * sizeof(yOutData[0]), yOutDeviceAddr,
173 size * sizeof(yOutData[0]), ACL_MEMCPY_DEVICE_TO_HOST);
174 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy yOut from device to host failed. ERROR: %d\n", ret);
175 return ret);
176 for (int64_t i = 0; i < size; i++) {
177 LOG_PRINT("y[%ld] is: %d\n", i, yOutData[i]);
178 }
179 size = GetShapeSize(mxscaleOutShape);
180 std::vector<uint8_t> mxscaleOutData(
181 size, 0); // C语言中无法直接打印fp8的数据,需要用uint8读出来,自行通过二进制转成fp8
182 ret = aclrtMemcpy(mxscaleOutData.data(), mxscaleOutData.size() * sizeof(mxscaleOutData[0]), mxscaleOutDeviceAddr,
183 size * sizeof(mxscaleOutData[0]), ACL_MEMCPY_DEVICE_TO_HOST);
184 CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy mxscaleOut from device to host failed. ERROR: %d\n", ret);
185 return ret);
186 for (int64_t i = 0; i < size; i++) {
187 LOG_PRINT("mxscaleOut[%ld] is: %d\n", i, mxscaleOutData[i]);
188 }
189 return ACL_SUCCESS;
190}
191 
192int main()
193{
194 // 1. (固定写法)device/stream初始化,参考acl API手册
195 // 根据自己的实际device填写deviceId
196 int32_t deviceId = 0;
197 aclrtStream stream;
198 auto ret = aclnnGroupedDynamicMxQuantTest(deviceId, stream);
199 CHECK_FREE_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnGroupedDynamicMxQuantTest failed. ERROR: %d\n", ret); return ret);
200 
201 Finalize(deviceId, stream);
202 return 0;
203}
Aquant/grouped_dynamic_mx_quant/op_api/aclnn_grouped_dynamic_mx_quant.cpp+195-0
@@ -0,0 +1,195 @@
1/**
2 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 * CANN Open Software License Agreement Version 2.0 (the "License").
5 * Please refer to the License for details. You may not use this file except in compliance with the License.
6 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 * See LICENSE in the root of the software repository for the full text of the License.
9 */
10#include <dlfcn.h>
11#include <new>
12#include "aclnn_grouped_dynamic_mx_quant.h"
13#include "grouped_dynamic_mx_quant.h"
14#include "level0/fault_injection.h"
15#include "aclnn_kernels/contiguous.h"
16#include "aclnn_kernels/reshape.h"
17#include "aclnn/aclnn_base.h"
18#include "aclnn_kernels/common/op_error_check.h"
19#include "acl/acl.h"
20#include "opdev/common_types.h"
21#include "opdev/data_type_utils.h"
22#include "opdev/format_utils.h"
23#include "opdev/op_dfx.h"
24#include "opdev/op_executor.h"
25#include "opdev/op_log.h"
26#include "opdev/platform.h"
27#include "opdev/shape_utils.h"
28#include "opdev/tensor_view_utils.h"
29#include "opdev/make_op_executor.h"
30 
31using namespace op;
32 
33#ifdef __cplusplus
34extern "C" {
35#endif
36static constexpr int64_t X_DIM_NUM = 2;
37static constexpr int64_t NUM_TWO = 2;
38static constexpr int64_t SCALE_DIM_NUM = 3;
39static constexpr uint64_t NUM_ZERO = 0 ;
40 
41static const std::initializer_list<op::DataType> X_DTYPE_SUPPORT_LIST = {op::DataType::DT_FLOAT16, op::DataType::DT_BF16};
42 
43static const std::initializer_list<op::DataType> GROUP_INDEX_DTYPE_SUPPORT_LIST = {op::DataType::DT_INT32};
44 
45static const std::initializer_list<op::DataType> OUTPUT_DTYPE_SUPPORT_LIST = {
46 op::DataType::DT_FLOAT8_E4M3FN, op::DataType::DT_FLOAT8_E5M2};
47 
48static const std::initializer_list<op::DataType> MXSCALE_DTYPE_SUPPORT_LIST = {
49 op::DataType::DT_FLOAT8_E8M0};
50 
51static inline bool CheckNotNull(const aclTensor* x, const aclTensor* groupIndex, const char* roundMode, const aclTensor* y, const aclTensor* mxscale) {
52 OP_CHECK_NULL(x, return false);
53 OP_CHECK_NULL(groupIndex, return false);
54 if (roundMode == nullptr) {
55 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "roundMode cannot be nullptr");
56 return false;
57 }
58 OP_CHECK_NULL(y, return false);
59 OP_CHECK_NULL(mxscale, return false);
60 return true;
61}
62 
63static bool CheckShape(const aclTensor* x, const aclTensor* groupIndex, int64_t blocksize, const aclTensor* y, const aclTensor* mxscale) {
64 auto xShape = x->GetViewShape();
65 auto groupShape = groupIndex->GetViewShape();
66 auto yShape = y->GetViewShape();
67 auto mxscaleShape = mxscale->GetViewShape();
68 OP_CHECK(xShape.GetDimNum() == X_DIM_NUM,
69 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "input x Dims is %ld, should be 2D.", xShape.GetDimNum()), return false);
70 OP_CHECK(groupShape.GetDimNum() == 1,
71 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "input groupIndex Dims is %ld, should be 1D.", groupShape.GetDimNum()), return false);
72 OP_CHECK(yShape.GetDimNum() == X_DIM_NUM,
73 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "output yShape Dims is %ld, should be 2D.", yShape.GetDimNum()), return false);
74 OP_CHECK(mxscaleShape.GetDimNum() == SCALE_DIM_NUM,
75 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "output mxscale Dims is %ld, should be 3D.", mxscaleShape.GetDimNum()), return false);
76 OP_CHECK_SHAPE_NOT_EQUAL(y, x, return false);
77 int64_t xDim0 = xShape.GetDim(0);
78 int64_t xDim1 = xShape.GetDim(1);
79 int64_t groupIndexDim0 = groupShape.GetDim(0);
80 int64_t mxscaleDim0 = mxscaleShape.GetDim(0);
81 int64_t mxscaleDim1 = mxscaleShape.GetDim(1);
82 int64_t mxscaleDim2 = mxscaleShape.GetDim(NUM_TWO);
83 int64_t mxscaleDim0Count = (xDim0/(blocksize * NUM_TWO) + groupIndexDim0);
84 OP_CHECK(mxscaleDim2 == NUM_TWO,
85 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "mxscale dim2 is %ld, should be 2.", mxscaleDim1), return false);
86 OP_CHECK(
87 xDim1 == mxscaleDim1,
88 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "mxscale dim1 is %ld, should be same as x dim1 (%ld).", mxscaleDim1, xDim1),
89 return false);
90 OP_CHECK(mxscaleDim0 == mxscaleDim0Count,
91 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "mxscale dim0 is %ld, should be same with mxscaleDim0Count (%ld).", mxscaleDim0, mxscaleDim0Count), return false);
92 return true;
93}
94 
95static bool CheckDtypeValid(const aclTensor* x, const aclTensor* groupIndex, const char* roundMode, int64_t dstType,
96 int64_t blocksize, const aclTensor* y, const aclTensor* mxscale) {
97 // 检查输入的数据类型是否在API支持的数据类型范围之内,需要根据api定义校验
98 bool IsRegbaseSocVersion = GetCurrentPlatformInfo().GetSocVersion() == SocVersion::ASCEND910_95;
99 if (IsRegbaseSocVersion) {
100 OP_CHECK_DTYPE_NOT_SUPPORT(x, X_DTYPE_SUPPORT_LIST, return false);
101 OP_CHECK_DTYPE_NOT_SUPPORT(groupIndex, GROUP_INDEX_DTYPE_SUPPORT_LIST, return false);
102 OP_CHECK_DTYPE_NOT_SUPPORT(y, OUTPUT_DTYPE_SUPPORT_LIST, return false);
103 OP_CHECK_DTYPE_NOT_SUPPORT(mxscale, MXSCALE_DTYPE_SUPPORT_LIST, return false);
104 const std::string mode = std::string(roundMode);
105 OP_CHECK(mode == "rint",
106 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "expected roundMode equals 'rint', get: %s", mode.c_str()),
107 return false);
108 OP_CHECK(blocksize == 32,
109 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "blocksize only support '32' now, get: %ld", blocksize),
110 return false);
111 OP_CHECK(static_cast<int64_t>(y->GetDataType()) == dstType,
112 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "dstType:%ld(%s) is must be the same as y dtype[%s].",
113 dstType, op::ToString(static_cast<op::DataType>(dstType)).GetString(), op::ToString(y->GetDataType()).GetString()),
114 return false);
115 } else {
116 OP_LOGE(ACLNN_ERR_RUNTIME_ERROR, "support for %s is not implemented",
117 op::ToString(GetCurrentPlatformInfo().GetSocVersion()).GetString());
118 return false;
119 }
120 return true;
121}
122 
123inline static aclnnStatus CheckParams(const aclTensor* x, const aclTensor* groupIndex, const char* roundMode, int64_t dstType, int64_t blocksize,
124 const aclTensor* y, const aclTensor* mxscale) {
125 CHECK_RET(CheckNotNull(x, groupIndex, roundMode, y, mxscale), ACLNN_ERR_PARAM_NULLPTR);
126 CHECK_RET(CheckDtypeValid(x, groupIndex, roundMode, dstType, blocksize, y, mxscale), ACLNN_ERR_PARAM_INVALID);
127 CHECK_RET(CheckShape(x, groupIndex, blocksize, y, mxscale), ACLNN_ERR_PARAM_INVALID);
128 return ACLNN_SUCCESS;
129}
130 
131aclnnStatus aclnnGroupedDynamicMxQuantGetWorkspaceSize(const aclTensor* x, const aclTensor* groupIndex,
132 const char* roundMode, int64_t dstType, int64_t blocksize,
133 const aclTensor* y, const aclTensor* mxscale,
134 uint64_t* workspaceSize, aclOpExecutor** executor) {
135 L2_DFX_PHASE_1(aclnnGroupedDynamicMxQuant, DFX_IN(x, groupIndex, roundMode, dstType, blocksize),
136 DFX_OUT(y, mxscale));
137 // 固定写法,创建OpExecutor
138 auto uniqueExecutor = CREATE_EXECUTOR();
139 CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR);
140 
141 // 固定写法,参数检查
142 auto ret = CheckParams(x, groupIndex, roundMode, dstType, blocksize, y, mxscale);
143 CHECK_RET(ret == ACLNN_SUCCESS, ret);
144 
145 // 空Tensor处理
146 if (groupIndex->IsEmpty()) {
147 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "groupIndex does not support empty values.");
148 return ACLNN_ERR_PARAM_INVALID;
149 }
150 
151 if (x->IsEmpty()) {
152 *workspaceSize = NUM_ZERO;
153 uniqueExecutor.ReleaseTo(executor);
154 return ACLNN_SUCCESS;
155 }
156 
157 // x如果非连续,需要转连续
158 auto selfContiguous = l0op::Contiguous(x, uniqueExecutor.get());
159 CHECK_RET(selfContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR);
160 
161 auto groupIndexContiguous = l0op::Contiguous(groupIndex, uniqueExecutor.get());
162 CHECK_RET(groupIndexContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR);
163 
164 auto result = l0op::GroupedDynamicMxQuant(selfContiguous, groupIndexContiguous, roundMode, dstType, blocksize,
165 uniqueExecutor.get());
166 const aclTensor *yOut = std::get<0>(result);
167 const aclTensor *mxscaleOut = std::get<1>(result);
168 // 如果出参y是非连续Tensor,需要把计算完的连续Tensor转非连续
169 auto viewCopyResult0 = l0op::ViewCopy(yOut, y, uniqueExecutor.get());
170 CHECK_RET(viewCopyResult0 != nullptr, ACLNN_ERR_INNER_NULLPTR);
171 if (!IsContiguous(mxscale)) {
172 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "mxscale must be contiguous.");
173 return ACLNN_ERR_PARAM_INVALID;
174 }
175 auto viewCopyResult1 = l0op::ViewCopy(mxscaleOut, mxscale, uniqueExecutor.get());
176 CHECK_RET(viewCopyResult1 != nullptr, ACLNN_ERR_INNER_NULLPTR);
177 
178 // 固定写法,获取计算过程中需要使用的workspace大小
179 *workspaceSize = uniqueExecutor->GetWorkspaceSize();
180 uniqueExecutor.ReleaseTo(executor); // 需要把 uniqueExecutor持有executor转移给executor
181 return ACLNN_SUCCESS;
182}
183 
184aclnnStatus aclnnGroupedDynamicMxQuant(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream) {
185 L2_DFX_PHASE_2(aclnnGroupedDynamicMxQuant);
186 auto ret = CommonOpExecutorRun(workspace, workspaceSize, executor, stream);
187 if (ret != ACLNN_SUCCESS) {
188 OP_LOGE(ACLNN_ERR_INNER, "This is an error in GroupedDynamicMxQuant launch aicore");
189 return ACLNN_ERR_INNER;
190 }
191 return ACLNN_SUCCESS;
192}
193#ifdef __cplusplus
194}
195#endif
Aquant/grouped_dynamic_mx_quant/op_api/aclnn_grouped_dynamic_mx_quant.h+56-0
@@ -0,0 +1,56 @@
1/**
2 * Copyright (c) 2025 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#ifndef ACLNN_GROUPED_DYNAMIC_MX_QUANT_H_
11#define ACLNN_GROUPED_DYNAMIC_MX_QUANT_H_
12 
13#include "aclnn/acl_meta.h"
14 
15#ifdef __cplusplus
16extern "C" {
17#endif
18 
19/**
20 * @brief aclnnGroupedDynamicMxQuant的第一段接口,根据具体的计算流程,计算workspace大小。
21 * @domain aclnn_ops_infer
22 *
23 * @param [in] x: 待进行GroupedDynamicMxQuant计算的入参。npu device侧的aclTensor,
24 * 数据类型支持float16, bfloat16, 数据格式支持ND,支持非连续的Tensor。
25 * @param [in] groupIndex: npu device侧的aclTensor,数据类型支持int32
26 * @param [in] roundMode: host侧的aclScalar,数据类型string,仅支持 "rint"
27 * @param [in] dstType: host侧的aclScalar, 数据类型int, 输入范围为{35, 36},分别对应输出y的数据类型为{35: FLOAT8_E5M2, 36: FLOAT8_E4M3FN}
28 * @param [in] blocksize: host侧的aclScalar, 数据类型int,仅支持 "32"
29 * @param [in] y: GroupedDynamicMxQuant计算的出参。npu device侧的aclTensor,
30 * 数据类型支持float8_e4m3fn, float8_e5m2, 数据格式支持ND,支持非连续的Tensor。
31 * @param [in] mxscale: GroupedDynamicMxQuant计算的出参。npu device侧的aclTensor,
32 * 数据类型支持float8_e8m0, 数据格式支持ND,不支持非连续的Tensor。
33 * @param [out] workspaceSize: 返回用户需要在npu device侧申请的workspace大小。
34 * @param [out] executor: 返回op执行器,包含算子计算流程。
35 * @return aclnnStatus: 返回状态码。
36 */
37__attribute__((visibility("default"))) aclnnStatus aclnnGroupedDynamicMxQuantGetWorkspaceSize(
38 const aclTensor* x, const aclTensor* groupIndex, const char* roundMode, int64_t dstType, int64_t blocksize, const aclTensor* y, const aclTensor* mxscale,
39 uint64_t* workspaceSize, aclOpExecutor** executor);
40 
41/**
42 * @brief aclnnGroupedDynamicMxQuant的第二段接口,用于执行计算。
43 * @param [in] workspace: 在npu device侧申请的workspace内存起址。
44 * @param [in] workspaceSize: 在npu device侧申请的workspace大小,由第一段接口aclnnGroupQuantGetWorkspaceSize获取。
45 * @param [in] executor: op执行器,包含了算子计算流程。
46 * @param [in] stream: acl stream流。
47 * @return aclnnStatus: 返回状态码。
48 */
49__attribute__((visibility("default"))) aclnnStatus aclnnGroupedDynamicMxQuant(void* workspace, uint64_t workspaceSize,
50 aclOpExecutor* executor, aclrtStream stream);
51 
52#ifdef __cplusplus
53}
54#endif
55 
56#endif // ACLNN_GROUPED_DYNAMIC_MX_QUANT_H_
Aquant/grouped_dynamic_mx_quant/op_api/grouped_dynamic_mx_quant.cpp+55-0
@@ -0,0 +1,55 @@
1/**
2 * Copyright (c) 2025 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#include "grouped_dynamic_mx_quant.h"
12#include "opdev/op_log.h"
13#include "opdev/op_dfx.h"
14#include "opdev/shape_utils.h"
15#include "opdev/make_op_executor.h"
16 
17using namespace op;
18 
19namespace l0op {
20OP_TYPE_REGISTER(GroupedDynamicMxQuant);
21static constexpr size_t NUM_TWO = 2;
22static op::Shape GetOutPutShape(const aclTensor* x, const aclTensor* groupIndex, int64_t blocksize) {
23 op::Shape outputShape;
24 auto axisDim0 = x->GetViewShape().GetDim(0);
25 auto groupIndexDim = groupIndex->GetViewShape().GetDim(0);
26 auto outputDim0 = (axisDim0 / (blocksize * NUM_TWO) + groupIndexDim);
27 outputShape.AppendDim(outputDim0);
28 outputShape.AppendDim(x->GetViewShape().GetDim(1));
29 outputShape.AppendDim(NUM_TWO);
30 return outputShape;
31}
32 
33std::tuple<aclTensor*, aclTensor*> GroupedDynamicMxQuant(const aclTensor* x, const aclTensor* groupIndex, const char* roundMode,
34 int64_t dstType, int64_t blocksize,aclOpExecutor* executor) {
35L0_DFX(GroupedDynamicMxQuant, x, groupIndex);
36auto yOut = executor->AllocTensor(x->GetStorageShape(), x->GetViewShape(), op::DataType(dstType),
37 x->GetStorageFormat(), x->GetOriginalFormat());
38 
39auto mxScaleShape = GetOutPutShape(x, groupIndex, blocksize);
40auto mxScaleOut = executor->AllocTensor(mxScaleShape, op::DataType::DT_FLOAT8_E8M0);
41if (yOut == nullptr || mxScaleOut == nullptr) {
42 OP_LOGE(ACLNN_ERR_INNER_NULLPTR, "alloc y or mxscale tensor failed.");
43 return std::tie(yOut, mxScaleOut);
44}
45 
46auto ret = ADD_TO_LAUNCHER_LIST_AICORE(GroupedDynamicMxQuant, OP_INPUT(x, groupIndex),
47 OP_OUTPUT(yOut, mxScaleOut), OP_ATTR(roundMode, dstType, blocksize));
48if (ret != ACLNN_SUCCESS) {
49 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "GroupedDynamicMxQuant launch kernel failed.");
50 return std::tuple<aclTensor*, aclTensor*>(nullptr, nullptr);
51}
52return std::tuple<aclTensor*, aclTensor*>(yOut, mxScaleOut);
53}
54 
55} // namespace l0op
Aquant/grouped_dynamic_mx_quant/op_api/grouped_dynamic_mx_quant.h+22-0
@@ -0,0 +1,22 @@
1/**
2 * Copyright (c) 2025 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#ifndef OP_API_INC_LEVEL0_GROUPED_DYNAMIC_MX_QUANT_QUANT_H_
11#define OP_API_INC_LEVEL0_GROUPED_DYNAMIC_MX_QUANT_QUANT_H_
12 
13#include <string>
14#include "opdev/op_executor.h"
15 
16namespace l0op {
17std::tuple<aclTensor*, aclTensor*> GroupedDynamicMxQuant(const aclTensor *x, const aclTensor *groupIndex,
18 const char *roundMode, int64_t dstType,
19 int64_t blocksize, aclOpExecutor *executor);
20} // l0op
21 
22#endif // OP_API_INC_LEVEL0_GROUP_QUANT_H_
Aquant/grouped_dynamic_mx_quant/op_graph/grouped_dynamic_mx_quant_proto.h+58-0
@@ -0,0 +1,58 @@
1/**
2 * Copyright (c) 2025 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 * \file quantize_ops.h
12 * \brief
13 */
14#ifndef OPS_BUILT_IN_OP_PROTO_INC_QUANTIZE_OPS_H_
15#define OPS_BUILT_IN_OP_PROTO_INC_QUANTIZE_OPS_H_
16#include "graph/operator_reg.h"
17 
18namespace ge {
19 
20/**
21* @brief Quantizes the input to mxfp8 group-wisely, according to group_index. \n
22 
23* @par Inputs:
24* @li x: A tensor of type float16 or bfloat16, specifying the input.
25* The shape only supports 2 dimensions.
26* @li group_index: A tensor of type int32, specifying the index of groups.
27* The shape only supports 1 dimension.
28 
29* @par Attributes:
30* @li round_mode: An optional string, specifying the quantization rounding mode.
31* Defaults and only supports "rint".
32* @li dst_type: An optional int, specifying the dtype of output y.
33* Defaults to FLOAT8_E5M2, only supports FLOAT8_E4M3FN or FLOAT8_E5M2.
34* @li blocksize: An optional int, specifying the block size of quantization.
35* Defaults and only supports 32.
36 
37* @par Outputs:
38* @li y: An output tensor of type FLOAT8_E4M3FN or FLOAT8_E5M2. It has the same shape and rank as input x.
39* @li mxscale: An output tensor of type FLOAT8_E8M0, the shape only supports 3 dimensions. \n
40* - mxscale.shape[0] = x.shape[0] / (blocksize * 2) + group_index.shape[0].
41* - mxscale.shape[1] = x.shape[1].
42* - mxscale.shape[2] = 2.
43 
44* @par Third-party framework compatibility
45* It is a custom operator. It has no corresponding operator in Caffe, Onnx, Tensorflow or Pytorch.
46*/
47REG_OP(GroupedDynamicMxQuant)
48 .INPUT(x, TensorType({DT_FLOAT16, DT_BF16}))
49 .INPUT(group_index, TensorType({DT_Int32}))
50 .OUTPUT(y, TensorType({DT_FLOAT8_E4M3FN, DT_FLOAT8_E5M2}))
51 .OUTPUT(mxscale, TensorType({DT_FLOAT8_E8M0}))
52 .ATTR(round_mode, String, "rint")
53 .ATTR(dst_type, Int, DT_FLOAT8_E5M2)
54 .ATTR(blocksize, Int, 32)
55 .OP_END_FACTORY_REG(GroupedDynamicMxQuant)
56} // namespace ge
57 
58#endif // OPS_BUILT_IN_OP_PROTO_INC_QUANTIZE_OPS_H_
Aquant/grouped_dynamic_mx_quant/op_host/arch35/grouped_dynamic_mx_quant_tiling_arch35.cpp+303-0
@@ -0,0 +1,303 @@
1/**
2 * Copyright (c) 2025 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 grouped_dynamic_mx_quant_tiling_arch35.cpp
13 * \brief
14 */
15 
16#include "grouped_dynamic_mx_quant_tiling_arch35.h"
17#include <cmath>
18#include "op_host/util/platform_util.h"
19#include "graph/utils/type_utils.h"
20#include "util/math_util.h"
21#include "register/op_impl_registry.h"
22 
23using namespace std;
24using namespace ge;
25using namespace Ops::Base;
26 
27namespace optiling {
28constexpr int64_t INDEX_ATTR_ROUND_MODE = 0;
29constexpr int64_t INDEX_ATTR_DST_DTYPE = 1;
30constexpr int64_t INDEX_ATTR_BLOCK_SIZE = 2;
31constexpr int64_t BYTES_OF_INPUT_TYPE = 2;
32constexpr int64_t DIGIT_TWO = 2;
33constexpr int64_t DIGIT_TEN = 10;
34constexpr int64_t N_BUFFER = 2;
35constexpr int64_t EXIST_NODE_NUM = 3;
36constexpr int64_t ATTR_BLOCK_SIZE = 32;
37constexpr int64_t SCALE_DIM_NUM = 3;
38constexpr size_t WORKSPACE_SIZE = 32;
39const std::set<ge::DataType> INPUT_SUPPORT_DTYPE_SET = { ge::DT_FLOAT16, ge::DT_BF16 };
40const std::set<ge::DataType> GROUPIDX_SUPPORT_DTYPE_SET = { ge::DT_INT32 };
41const std::set<ge::DataType> Y_SUPPORT_DTYPE_SET = { ge::DT_FLOAT8_E4M3FN, ge::DT_FLOAT8_E5M2 };
42const std::set<ge::DataType> OUTPUT_SUPPORT_DTYPE_SET = { ge::DT_FLOAT8_E8M0 };
43 
44static ge::graphStatus GetAttr(const gert::TilingContext *context, GroupedDynamicMxQuantTilingParam &tilingParam)
45{
46 OP_LOGD(context->GetNodeName(), "GetAttr begin.");
47 auto *attrs = context->GetAttrs();
48 OP_CHECK_NULL_WITH_CONTEXT(context, attrs);
49
50 auto *attrRoundMode = attrs->GetAttrPointer<char>(INDEX_ATTR_ROUND_MODE);
51 OP_CHECK_NULL_WITH_CONTEXT(context, attrRoundMode);
52 std::string roundModeStr = attrRoundMode;
53 OP_CHECK_IF((roundModeStr != "rint"),
54 OP_LOGE(context->GetNodeName(),
55 "invalid round_mode:%s; round_mode only supports rint", roundModeStr.c_str()),
56 return ge::GRAPH_FAILED);
57 
58 auto *attrDstType = attrs->GetAttrPointer<int64_t>(INDEX_ATTR_DST_DTYPE);
59 OP_CHECK_NULL_WITH_CONTEXT(context, attrDstType);
60 int checkDstType = static_cast<int>(*attrDstType);
61 OP_CHECK_IF((tilingParam.outDtype == ge::DT_FLOAT8_E4M3FN && checkDstType != 36) ||
62 (tilingParam.outDtype == ge::DT_FLOAT8_E5M2 && checkDstType != 35),
63 OP_LOGE(context->GetNodeName(),
64 "y's data type and dst_type is not corresponded, y's data type: FLOAT8_E4M3FN/FLOAT8_E5M2 correspond to dst_type: 36/35."),
65 return ge::GRAPH_FAILED);
66 
67 auto *attrBlockSize = attrs->GetAttrPointer<int64_t>(INDEX_ATTR_BLOCK_SIZE);
68 OP_CHECK_NULL_WITH_CONTEXT(context, attrBlockSize);
69 tilingParam.blockSize = static_cast<int64_t>(*attrBlockSize);
70 OP_CHECK_IF(tilingParam.blockSize != ATTR_BLOCK_SIZE,
71 OP_LOGE(context->GetNodeName(),
72 "The blocksize only supports 32."),
73 return ge::GRAPH_FAILED);
74 
75 return ge::GRAPH_SUCCESS;
76}
77 
78static ge::graphStatus CheckDtype(const gert::TilingContext *context, GroupedDynamicMxQuantTilingParam &tilingParam)
79{
80 OP_LOGD(context->GetNodeName(), "CheckDtype begin.");
81 auto inputXPtr = context->GetInputDesc(0);
82 OP_CHECK_NULL_WITH_CONTEXT(context, inputXPtr);
83 tilingParam.inDtype = inputXPtr->GetDataType();
84 OP_CHECK_IF(INPUT_SUPPORT_DTYPE_SET.count(tilingParam.inDtype) == 0,
85 OP_LOGE(context->GetNodeName(),
86 "Input x's data type is [%s], current only supports FLOAT16/BFLOAT16.",
87 ge::TypeUtils::DataTypeToSerialString(tilingParam.inDtype).c_str()),
88 return ge::GRAPH_FAILED);
89 
90 auto groupIndexPtr = context->GetInputDesc(1);
91 OP_CHECK_NULL_WITH_CONTEXT(context, groupIndexPtr);
92 auto groupIndexDtype = groupIndexPtr->GetDataType();
93 OP_CHECK_IF(GROUPIDX_SUPPORT_DTYPE_SET.count(groupIndexDtype) == 0,
94 OP_LOGE(context->GetNodeName(),
95 "group_index's data type is [%s], current only supports Int32.",
96 ge::TypeUtils::DataTypeToSerialString(groupIndexDtype).c_str()),
97 return ge::GRAPH_FAILED);
98 
99 auto outputYPtr = context->GetOutputDesc(0);
100 OP_CHECK_NULL_WITH_CONTEXT(context, outputYPtr);
101 tilingParam.outDtype = outputYPtr->GetDataType();
102 OP_CHECK_IF(Y_SUPPORT_DTYPE_SET.count(tilingParam.outDtype) == 0,
103 OP_LOGE(context->GetNodeName(),
104 "Output y's data type is [%s], current only supports FLOAT8_E4M3FN/FLOAT8_E5M2.",
105 ge::TypeUtils::DataTypeToSerialString(tilingParam.outDtype).c_str()),
106 return ge::GRAPH_FAILED);
107 
108 auto outputMxScalePtr = context->GetOutputDesc(1);
109 OP_CHECK_NULL_WITH_CONTEXT(context, outputMxScalePtr);
110 auto scaleDtype = outputMxScalePtr->GetDataType();
111 OP_CHECK_IF(OUTPUT_SUPPORT_DTYPE_SET.count(scaleDtype) == 0,
112 OP_LOGE(context->GetNodeName(),
113 "Input mxscale's data type is [%s], current only supports FLOAT8_E8M0.",
114 ge::TypeUtils::DataTypeToSerialString(scaleDtype).c_str()),
115 return ge::GRAPH_FAILED);
116 
117 return ge::GRAPH_SUCCESS;
118}
119 
120static ge::graphStatus CheckShape(const gert::TilingContext *context, GroupedDynamicMxQuantTilingParam &tilingParam)
121{
122 OP_LOGD(context->GetNodeName(), "CheckShape begin.");
123 auto xShapePtr = context->GetInputShape(0);
124 OP_CHECK_NULL_WITH_CONTEXT(context, xShapePtr);
125 auto xShape = xShapePtr->GetStorageShape();
126 
127 auto groupIndexShapePtr = context->GetInputShape(1);
128 OP_CHECK_NULL_WITH_CONTEXT(context, groupIndexShapePtr);
129 auto groupIndexShape = groupIndexShapePtr->GetStorageShape();
130 
131 auto yShapePtr = context->GetOutputShape(0);
132 OP_CHECK_NULL_WITH_CONTEXT(context, yShapePtr);
133 auto yShape = yShapePtr->GetStorageShape();
134 
135 auto mxScaleShapePtr = context->GetOutputShape(1);
136 OP_CHECK_NULL_WITH_CONTEXT(context, mxScaleShapePtr);
137 auto mxScaleShape = mxScaleShapePtr->GetStorageShape();
138 
139 OP_CHECK_IF(xShape != yShape,
140 OP_LOGE(context->GetNodeName(),
141 "The shape of output y must be same with shape of input x."),
142 return ge::GRAPH_FAILED);
143 OP_CHECK_IF(xShape.GetDimNum() != 2,
144 OP_LOGE(context->GetNodeName(),
145 "The shape of input x must be 2-D."),
146 return ge::GRAPH_FAILED);
147 OP_CHECK_IF(groupIndexShape.GetDimNum() != 1,
148 OP_LOGE(context->GetNodeName(),
149 "The shape of input group_index must be 1-D."),
150 return ge::GRAPH_FAILED);
151 OP_CHECK_IF(mxScaleShape.GetDimNum() != SCALE_DIM_NUM,
152 OP_LOGE(context->GetNodeName(),
153 "The shape of output mxscale must be 3-D."),
154 return ge::GRAPH_FAILED);
155 
156 tilingParam.groupSize = groupIndexShape.GetDim(0);
157 tilingParam.preAxisSize = xShape.GetDim(0);
158 tilingParam.postAxisSize = xShape.GetDim(1);
159 OP_CHECK_IF(tilingParam.groupSize == 0,
160 OP_LOGE(context->GetNodeName(),
161 "group_index does not support empty tensor."),
162 return ge::GRAPH_FAILED);
163 
164 xShape.SetDim(0, tilingParam.preAxisSize/(tilingParam.blockSize *DIGIT_TWO)+tilingParam.groupSize);
165 xShape.SetDim(1, tilingParam.postAxisSize * DIGIT_TWO);
166 OP_CHECK_IF(
167 mxScaleShape[0] != xShape[0] || mxScaleShape[1] != tilingParam.postAxisSize ||
168 mxScaleShape[SCALE_DIM_NUM - 1] != DIGIT_TWO,
169 OP_LOGE(
170 context->GetNodeName(),
171 "The shape of output mxscale is incorrect, it should be [x.shape[0] / (2 * "
172 "blocksize) + group_index.shape[0], x.shape[1], 2]."),
173 return ge::GRAPH_FAILED);
174 return ge::GRAPH_SUCCESS;
175}
176 
177static ge::graphStatus GetPlatInfo(const gert::TilingContext *context, GroupedDynamicMxQuantTilingParam &tilingParam)
178{
179 OP_LOGD(context->GetNodeName(), "GetPlatInfo begin.");
180 auto platformInfo = context->GetPlatformInfo();
181 OP_CHECK_NULL_WITH_CONTEXT(context, platformInfo);
182 auto ascendcPlatform = platform_ascendc::PlatformAscendC(platformInfo);
183 tilingParam.totalCoreNum = ascendcPlatform.GetCoreNumAiv();
184 OP_CHECK_IF((tilingParam.totalCoreNum <= 0),
185 OP_LOGE(context->GetNodeName(), "Failed to get core num."), return ge::GRAPH_FAILED);
186 uint64_t ubSize;
187 ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::UB, ubSize);
188 tilingParam.ubSize = static_cast<int64_t>(ubSize);
189 OP_CHECK_IF((tilingParam.ubSize <= 0),
190 OP_LOGE(context->GetNodeName(), "Failed to get ub size."), return ge::GRAPH_FAILED);
191 tilingParam.vfLen = Ops::Base::GetVRegSize(context);
192 return ge::GRAPH_SUCCESS;
193}
194 
195static ge::graphStatus DoTiling(const gert::TilingContext *context, GroupedDynamicMxQuantTilingParam &tilingParam)
196{
197 OP_LOGD(context->GetNodeName(), "DoTiling begin.");
198 // 计算tilingkey
199 // 十位数为1、2,分别表示输入类型是float16、bfloat16;
200 int64_t hundredDigit = tilingParam.inDtype == DT_FLOAT16 ? 1 : DIGIT_TWO;
201 // 个位数为1、2,分别表示输出类型是float8_e4m3fn、float8_e5m2
202 int64_t tenDigit = tilingParam.outDtype == DT_FLOAT8_E4M3FN? 1: 2;
203 tilingParam.tilingKey = hundredDigit * DIGIT_TEN + tenDigit;
204 
205 // 计算ubFactor
206 const int64_t cacheline = static_cast<int64_t>(tilingParam.vfLen / BYTES_OF_INPUT_TYPE);
207 int64_t maxUbAvailable = tilingParam.ubSize / N_BUFFER / EXIST_NODE_NUM;
208 // 按照2倍blocksize对齐,保证e8m0_2可以ub内交织计算
209 tilingParam.maxUbCol = static_cast<int64_t>(maxUbAvailable / static_cast<int64_t>(tilingParam.vfLen) / (tilingParam.blockSize*DIGIT_TWO) * (tilingParam.blockSize*DIGIT_TWO));
210 tilingParam.ubFactor = cacheline;
211 tilingParam.uo = CeilDiv(tilingParam.postAxisSize, tilingParam.ubFactor);
212 tilingParam.tailUbFactor = tilingParam.postAxisSize - (tilingParam.uo - 1) * tilingParam.ubFactor;
213 
214 int64_t spliteCoreData = tilingParam.uo * tilingParam.groupSize;
215 int64_t coreData = CeilDiv(spliteCoreData, tilingParam.totalCoreNum);
216 tilingParam.usedCoreNum = CeilDiv(spliteCoreData, coreData);
217 tilingParam.blockFactor = CeilDiv(spliteCoreData, tilingParam.usedCoreNum);
218 tilingParam.tailBlockFactor = spliteCoreData - (tilingParam.usedCoreNum - 1) * tilingParam.blockFactor;
219 
220 return ge::GRAPH_SUCCESS;
221}
222 
223inline static ge::graphStatus SetTilingData(gert::TilingContext *context,
224 const GroupedDynamicMxQuantTilingParam &tilingParam, GroupedDynamicMxQuantTilingData &tilingData)
225{
226 OP_LOGD(context->GetNodeName(), "SetTilingData begin.");
227 tilingData.set_totalCoreNum(tilingParam.totalCoreNum);
228 tilingData.set_usedCoreNum(tilingParam.usedCoreNum);
229 tilingData.set_blockFactor(tilingParam.blockFactor);
230 tilingData.set_tailBlockFactor(tilingParam.tailBlockFactor);
231 tilingData.set_uo(tilingParam.uo);
232 tilingData.set_maxUbCol(tilingParam.maxUbCol);
233 tilingData.set_ubFactor(tilingParam.ubFactor);
234 tilingData.set_tailUbFactor(tilingParam.tailUbFactor);
235 tilingData.set_blockSize(tilingParam.blockSize);
236 tilingData.set_preAxisSize(tilingParam.preAxisSize);
237 tilingData.set_postAxisSize(tilingParam.postAxisSize);
238 
239 OP_CHECK_IF(tilingData.GetDataSize() > context->GetRawTilingData()->GetCapacity(),
240 OP_LOGE(context->GetNodeName(), "tiling datasize: %zu is bigger than %zu",
241 tilingData.GetDataSize(), context->GetRawTilingData()->GetCapacity()),
242 return ge::GRAPH_FAILED);
243 tilingData.SaveToBuffer(context->GetRawTilingData()->GetData(), context->GetRawTilingData()->GetCapacity());
244 context->GetRawTilingData()->SetDataSize(tilingData.GetDataSize());
245 context->SetBlockDim(tilingData.get_usedCoreNum());
246 context->SetTilingKey(tilingParam.tilingKey);
247 size_t *workspaces = context->GetWorkspaceSizes(1);
248 OP_CHECK_NULL_WITH_CONTEXT(context, workspaces);
249 workspaces[0] = WORKSPACE_SIZE;
250 return ge::GRAPH_SUCCESS;
251}
252 
253inline static void PrintTilingData(const gert::TilingContext *context, GroupedDynamicMxQuantTilingData &tilingData)
254{
255 OP_LOGI(context->GetNodeName(), "tilingData is totalCoreNum:%ld, usedCoreNum:%ld, ubFactor:%ld, \
256 tailUbFactor:%ld, blockFactor:%ld, tailBlockFactor:%ld, uo:%ld, maxUbCol:%ld, blockSize:%ld, preAxisSize:%ld, postAxisSize:%ld",
257 tilingData.get_totalCoreNum(), tilingData.get_usedCoreNum(), tilingData.get_ubFactor(),
258 tilingData.get_tailUbFactor(), tilingData.get_blockFactor(), tilingData.get_tailBlockFactor(),
259 tilingData.get_uo(), tilingData.get_maxUbCol(), tilingData.get_blockSize(),
260 tilingData.get_preAxisSize(), tilingData.get_postAxisSize());
261}
262 
263ge::graphStatus Tiling4GroupedDynamicMxQuant(gert::TilingContext *context)
264{
265 OP_LOGD(context->GetNodeName(), "Tiling4GroupedDynamicMxQuant running begin.");
266 
267 GroupedDynamicMxQuantTilingParam tilingParam;
268 
269 OP_CHECK_IF(CheckDtype(context, tilingParam) != ge::GRAPH_SUCCESS,
270 OP_LOGE(context->GetNodeName(), "The data type check failed."), return ge::GRAPH_FAILED);
271 
272 OP_CHECK_IF(GetAttr(context, tilingParam) != ge::GRAPH_SUCCESS,
273 OP_LOGE(context->GetNodeName(), "The attr get failed."), return ge::GRAPH_FAILED);
274 
275 OP_CHECK_IF(CheckShape(context, tilingParam) != ge::GRAPH_SUCCESS,
276 OP_LOGE(context->GetNodeName(), "The shape check failed."), return ge::GRAPH_FAILED);
277 
278 OP_CHECK_IF(GetPlatInfo(context, tilingParam) != ge::GRAPH_SUCCESS,
279 OP_LOGE(context->GetNodeName(), "GetPlatInfo failed."), return ge::GRAPH_FAILED);
280 
281 OP_CHECK_IF(DoTiling(context, tilingParam) != ge::GRAPH_SUCCESS,
282 OP_LOGE(context->GetNodeName(), "DoTiling failed."), return ge::GRAPH_FAILED);
283 
284 GroupedDynamicMxQuantTilingData tilingData;
285 OP_CHECK_IF(SetTilingData(context, tilingParam, tilingData) != ge::GRAPH_SUCCESS,
286 OP_LOGE(context->GetNodeName(), "SetContext fail."),
287 return ge::GRAPH_FAILED);
288 
289 PrintTilingData(context, tilingData);
290 return ge::GRAPH_SUCCESS;
291}
292 
293ge::graphStatus TilingPrepare4GroupedDynamicMxQuant(gert::TilingParseContext *context)
294{
295 OP_LOGD(context->GetNodeName(), "TilingPrepare4GroupedDynamicMxQuant entering.");
296 return ge::GRAPH_SUCCESS;
297}
298 
299// register tiling interface of the GroupedDynamicMxQuant op.
300IMPL_OP_OPTILING(GroupedDynamicMxQuant)
301 .Tiling(Tiling4GroupedDynamicMxQuant)
302 .TilingParse<GroupedDynamicMxQuantCompileInfo>(TilingPrepare4GroupedDynamicMxQuant);
303}
Aquant/grouped_dynamic_mx_quant/op_host/arch35/grouped_dynamic_mx_quant_tiling_arch35.h+66-0
@@ -0,0 +1,66 @@
1/**
2 * Copyright (c) 2025 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 grouped_dynamic_mx_quant_tiling_arch35.h
13 * \brief
14 */
15 
16#ifndef AIR_CXX_RUNTIME_V2_OP_IMPL_GROUPED_DYNAMIC_MX_QUANT_H
17#define AIR_CXX_RUNTIME_V2_OP_IMPL_GROUPED_DYNAMIC_MX_QUANT_H
18 
19#include "register/tilingdata_base.h"
20#include "graph/types.h"
21 
22namespace optiling {
23BEGIN_TILING_DATA_DEF(GroupedDynamicMxQuantTilingData)
24TILING_DATA_FIELD_DEF(int64_t, totalCoreNum);
25TILING_DATA_FIELD_DEF(int64_t, usedCoreNum); // 实际使用的核数
26TILING_DATA_FIELD_DEF(int64_t, blockFactor); // 单核循环次数
27TILING_DATA_FIELD_DEF(int64_t, tailBlockFactor); // 尾核循环次数
28TILING_DATA_FIELD_DEF(int64_t, uo); // 切分轴上的循环次数
29TILING_DATA_FIELD_DEF(int64_t, maxUbCol); // 单次循环要处理的数据大小
30TILING_DATA_FIELD_DEF(int64_t, ubFactor); // 单次循环要处理的数据大小
31TILING_DATA_FIELD_DEF(int64_t, tailUbFactor); // 尾循环要处理的数据大小
32TILING_DATA_FIELD_DEF(int64_t, blockSize); // 进行微缩的数据块大小
33TILING_DATA_FIELD_DEF(int64_t, preAxisSize); // 输入row长度
34TILING_DATA_FIELD_DEF(int64_t, postAxisSize); // 输入column长度
35END_TILING_DATA_DEF;
36 
37REGISTER_TILING_DATA_CLASS(GroupedDynamicMxQuant, GroupedDynamicMxQuantTilingData)
38 
39struct GroupedDynamicMxQuantCompileInfo {
40 int64_t coreNum = 0;
41 int64_t ubSize = 0;
42};
43 
44struct GroupedDynamicMxQuantTilingParam {
45 int64_t totalCoreNum { 0 };
46 int64_t usedCoreNum { 0 };
47 int64_t blockFactor { 0 };
48 int64_t tailBlockFactor { 0 };
49 int64_t uo { 1 };
50 int64_t maxUbCol { 1 };
51 int64_t ubFactor { 0 };
52 int64_t tailUbFactor { 0 };
53 int64_t blockSize { 0 };
54 int64_t preAxisSize {0};
55 int64_t postAxisSize { 1 };
56 bool isTailAxis { false };
57 int64_t ubSize { 0 };
58 uint32_t vfLen { 0 };
59 int64_t tilingKey { 0 };
60 int64_t groupSize {1};
61 ge::DataType inDtype {ge::DT_FLOAT16};
62 ge::DataType outDtype {ge::DT_FLOAT8_E4M3FN};
63};
64 
65} // namespace optiling
66#endif // AIR_CXX_RUNTIME_V2_OP_IMPL_GROUPED_DYNAMIC_MX_QUANT_H
Aquant/grouped_dynamic_mx_quant/op_host/config/ascend910_95/grouped_dynamic_mx_quant_binary.json+277-0
@@ -0,0 +1,277 @@
1{
2 "op_type": "GroupedDynamicMxQuant",
3 "op_list": [
4 {
5 "bin_filename": "GroupedDynamicMxQuant_bf16toe4m3",
6 "inputs": [
7 {
8 "name": "x",
9 "index": 0,
10 "dtype": "bfloat16",
11 "format": "ND",
12 "paramType": "required",
13 "shape": [
14 -2
15 ],
16 "format_match_mode": "FormatAgnostic"
17 },
18 {
19 "name": "group_index",
20 "index": 1,
21 "dtype": "int32",
22 "format": "ND",
23 "paramType": "required",
24 "shape": [
25 -2
26 ],
27 "format_match_mode": "FormatAgnostic"
28 }
29 ],
30 "outputs": [
31 {
32 "name": "y",
33 "index": 0,
34 "dtype": "float8_e4m3fn",
35 "format": "ND",
36 "paramType": "required",
37 "shape": [
38 -2
39 ],
40 "format_match_mode": "FormatAgnostic"
41 },
42 {
43 "name": "mxscale",
44 "index": 1,
45 "dtype": "float8_e8m0",
46 "format": "ND",
47 "paramType": "required",
48 "shape": [
49 -2
50 ],
51 "format_match_mode": "FormatAgnostic"
52 }
53 ],
54 "attrs": [
55 {
56 "name": "round_mode",
57 "dtype": "string",
58 "value": null
59 },
60 {
61 "name": "dst_type",
62 "dtype": "int",
63 "value": null
64 },
65 {
66 "name": "blocksize",
67 "dtype": "int",
68 "value": null
69 }
70 ]
71 },
72 {
73 "bin_filename": "GroupedDynamicMxQuant_bf16toe5m2",
74 "inputs": [
75 {
76 "name": "x",
77 "index": 0,
78 "dtype": "bfloat16",
79 "format": "ND",
80 "paramType": "required",
81 "shape": [
82 -2
83 ],
84 "format_match_mode": "FormatAgnostic"
85 },
86 {
87 "name": "group_index",
88 "index": 1,
89 "dtype": "int32",
90 "format": "ND",
91 "paramType": "required",
92 "shape": [
93 -2
94 ],
95 "format_match_mode": "FormatAgnostic"
96 }
97 ],
98 "outputs": [
99 {
100 "name": "y",
101 "index": 0,
102 "dtype": "float8_e5m2",
103 "format": "ND",
104 "paramType": "required",
105 "shape": [
106 -2
107 ],
108 "format_match_mode": "FormatAgnostic"
109 },
110 {
111 "name": "mxscale",
112 "index": 1,
113 "dtype": "float8_e8m0",
114 "format": "ND",
115 "paramType": "required",
116 "shape": [
117 -2
118 ],
119 "format_match_mode": "FormatAgnostic"
120 }
121 ],
122 "attrs": [
123 {
124 "name": "round_mode",
125 "dtype": "string",
126 "value": null
127 },
128 {
129 "name": "dst_type",
130 "dtype": "int",
131 "value": null
132 },
133 {
134 "name": "blocksize",
135 "dtype": "int",
136 "value": null
137 }
138 ]
139 },
140 {
141 "bin_filename": "GroupedDynamicMxQuant_fp16toe4m3",
142 "inputs": [
143 {
144 "name": "x",
145 "index": 0,
146 "dtype": "float16",
147 "format": "ND",
148 "paramType": "required",
149 "shape": [
150 -2
151 ],
152 "format_match_mode": "FormatAgnostic"
153 },
154 {
155 "name": "group_index",
156 "index": 1,
157 "dtype": "int32",
158 "format": "ND",
159 "paramType": "required",
160 "shape": [
161 -2
162 ],
163 "format_match_mode": "FormatAgnostic"
164 }
165 ],
166 "outputs": [
167 {
168 "name": "y",
169 "index": 0,
170 "dtype": "float8_e4m3fn",
171 "format": "ND",
172 "paramType": "required",
173 "shape": [
174 -2
175 ],
176 "format_match_mode": "FormatAgnostic"
177 },
178 {
179 "name": "mxscale",
180 "index": 1,
181 "dtype": "float8_e8m0",
182 "format": "ND",
183 "paramType": "required",
184 "shape": [
185 -2
186 ],
187 "format_match_mode": "FormatAgnostic"
188 }
189 ],
190 "attrs": [
191 {
192 "name": "round_mode",
193 "dtype": "string",
194 "value": null
195 },
196 {
197 "name": "dst_type",
198 "dtype": "int",
199 "value": null
200 },
201 {
202 "name": "blocksize",
203 "dtype": "int",
204 "value": null
205 }
206 ]
207 },
208 {
209 "bin_filename": "GroupedDynamicMxQuant_fp16toe5m2",
210 "inputs": [
211 {
212 "name": "x",
213 "index": 0,
214 "dtype": "float16",
215 "format": "ND",
216 "paramType": "required",
217 "shape": [
218 -2
219 ],
220 "format_match_mode": "FormatAgnostic"
221 },
222 {
223 "name": "group_index",
224 "index": 1,
225 "dtype": "int32",
226 "format": "ND",
227 "paramType": "required",
228 "shape": [
229 -2
230 ],
231 "format_match_mode": "FormatAgnostic"
232 }
233 ],
234 "outputs": [
235 {
236 "name": "y",
237 "index": 0,
238 "dtype": "float8_e5m2",
239 "format": "ND",
240 "paramType": "required",
241 "shape": [
242 -2
243 ],
244 "format_match_mode": "FormatAgnostic"
245 },
246 {
247 "name": "mxscale",
248 "index": 1,
249 "dtype": "float8_e8m0",
250 "format": "ND",
251 "paramType": "required",
252 "shape": [
253 -2
254 ],
255 "format_match_mode": "FormatAgnostic"
256 }
257 ],
258 "attrs": [
259 {
260 "name": "round_mode",
261 "dtype": "string",
262 "value": null
263 },
264 {
265 "name": "dst_type",
266 "dtype": "int",
267 "value": null
268 },
269 {
270 "name": "blocksize",
271 "dtype": "int",
272 "value": null
273 }
274 ]
275 }
276 ]
277}
Aquant/grouped_dynamic_mx_quant/op_host/config/ascend910_95/grouped_dynamic_mx_quant_simplified_key.ini+13-0
@@ -0,0 +1,13 @@
1; 该文件主要影响 opc 工具 编译二进制kernel时, --simplified_key_mode 选项中填写的值,格式如下所示:
2; [某算子]
3; default=xx
4; ascendxx=xx
5; 其中,default为默认mode,ascnedxx为可选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[GroupedDynamicMxQuant]
13default=0
Aquant/grouped_dynamic_mx_quant/op_host/grouped_dynamic_mx_quant_def.cpp+63-0
@@ -0,0 +1,63 @@
1/**
2 * Copyright (c) 2025 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 grouped_dynamic_mx_quant.cpp
13 * \brief
14 */
15 
16#include <cstdint>
17#include "register/op_def_registry.h"
18 
19namespace ops {
20constexpr int32_t BLOCK_SIZE = 32;
21class GroupedDynamicMxQuant : public OpDef {
22public:
23 explicit GroupedDynamicMxQuant(const char* name) : OpDef(name)
24 {
25 this->Input("x")
26 .ParamType(REQUIRED)
27 .DataType({ge::DT_FLOAT16, ge::DT_BF16, ge::DT_FLOAT16, ge::DT_BF16})
28 .Format({ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND})
29 .UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND})
30 .AutoContiguous();
31 this->Input("group_index")
32 .ParamType(REQUIRED)
33 .DataType({ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, ge::DT_INT32})
34 .Format({ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND})
35 .UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND})
36 .AutoContiguous();
37 this->Output("y")
38 .ParamType(REQUIRED)
39 .DataType({ge::DT_FLOAT8_E4M3FN, ge::DT_FLOAT8_E4M3FN, ge::DT_FLOAT8_E5M2,ge::DT_FLOAT8_E5M2})
40 .Format({ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND})
41 .UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND});
42 this->Output("mxscale")
43 .ParamType(REQUIRED)
44 .DataType({ge::DT_FLOAT8_E8M0, ge::DT_FLOAT8_E8M0, ge::DT_FLOAT8_E8M0, ge::DT_FLOAT8_E8M0})
45 .Format({ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND})
46 .UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND});
47 this->Attr("round_mode").AttrType(OPTIONAL).String("rint");
48 this->Attr("dst_type").AttrType(OPTIONAL).Int(ge::DT_FLOAT8_E5M2);
49 this->Attr("blocksize").AttrType(OPTIONAL).Int(BLOCK_SIZE);
50 
51 OpAICoreConfig aicoreConfig;
52 aicoreConfig.DynamicCompileStaticFlag(true)
53 .DynamicFormatFlag(false)
54 .DynamicRankSupportFlag(true)
55 .DynamicShapeSupportFlag(true)
56 .NeedCheckSupportFlag(false)
57 .PrecisionReduceFlag(true);
58 this->AICore().AddConfig("ascend910_95", aicoreConfig);
59 }
60};
61 
62OP_ADD(GroupedDynamicMxQuant);
63} // namespace ops
Aquant/grouped_dynamic_mx_quant/op_host/grouped_dynamic_mx_quant_infershape.cpp+125-0
@@ -0,0 +1,125 @@
1/**
2 * Copyright (c) 2025 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 grouped_dynamic_mx_quant.cc
13 * \brief
14 */
15 
16#include "log/log.h"
17#include "register/op_impl_registry.h"
18#include "op_host/util/shape_util.h"
19 
20using namespace ge;
21namespace ops {
22constexpr size_t INDEX_ATTR_DST_TYPE = 1;
23constexpr size_t INDEX_ATTR_BLOCK_SIZE = 2;
24constexpr size_t SCALE_DIM_NUM = 3;
25static const int32_t DTYPE_FLOAT8_E5M2 = 35;
26static const int32_t DTYPE_FLOAT8_E4M3FN = 36;
27 
28template <typename T>
29static std::string Shape2String(const T& shape) {
30 std::ostringstream oss;
31 oss << "[";
32 if (shape.GetDimNum() > 0) {
33 for (size_t i = 0; i < shape.GetDimNum() - 1; ++i) {
34 oss << shape.GetDim(i) << ", ";
35 }
36 oss << shape.GetDim(shape.GetDimNum() - 1);
37 }
38 oss << "]";
39 return oss.str();
40}
41 
42graphStatus InferShapeForGroupedDynamicMxQuant(gert::InferShapeContext* context) {
43 OP_LOGD(context->GetNodeName(), "Begin to do InferShapeForGroupedDynamicMxQuant");
44 const gert::Shape* xShape = context->GetInputShape(0);
45 OP_CHECK_NULL_WITH_CONTEXT(context, xShape);
46 const gert::Shape* groupIdxShape = context->GetInputShape(1);
47 OP_CHECK_NULL_WITH_CONTEXT(context, groupIdxShape);
48 
49 gert::Shape* yShape = context->GetOutputShape(0);
50 OP_CHECK_NULL_WITH_CONTEXT(context, yShape);
51 *yShape = *xShape;
52 
53 gert::Shape* scaleShape = context->GetOutputShape(1);
54 OP_CHECK_NULL_WITH_CONTEXT(context, scaleShape);
55 
56 auto attrsPtr = context->GetAttrs();
57 OP_CHECK_NULL_WITH_CONTEXT(context, attrsPtr);
58
59 const int32_t *blockSize = attrsPtr->GetAttrPointer<int32_t>(INDEX_ATTR_BLOCK_SIZE);
60 OP_CHECK_NULL_WITH_CONTEXT(context, blockSize);
61 OP_CHECK_IF(static_cast<int64_t>(*blockSize) != 32,
62 OP_LOGE(context->GetNodeName(), "blockSize is invalid, must be 32"),
63 return ge::GRAPH_FAILED);
64 size_t xShapeSize = xShape->GetDimNum();
65 size_t groupIdxShapeSize = groupIdxShape->GetDimNum();
66 OP_CHECK_IF(groupIdxShapeSize != 1,
67 OP_LOGE(context->GetNodeName(),
68 "group_index's shape must be 1D, but is %lu", groupIdxShapeSize),
69 return ge::GRAPH_FAILED);
70 int64_t groupIdxDim0 = groupIdxShape->GetDim(0);
71 OP_CHECK_IF(groupIdxDim0 == 0,
72 OP_LOGE(context->GetNodeName(), "group_index does not support empty tensor"),
73 return ge::GRAPH_FAILED);
74 
75 // dynamic -2 (input x)
76 if (Ops::Base::IsUnknownRank(*xShape)) {
77 OP_LOGD(context->GetNodeName(), "input x is UnknownRank, set outputs' shape to -2");
78 *scaleShape = *xShape;
79 return ge::GRAPH_SUCCESS;
80 } else {
81 OP_CHECK_IF(xShapeSize != 2,
82 OP_LOGE(context->GetNodeName(),
83 "input x is not UnknownRank, shape must be 2D, but is %lu", xShapeSize),
84 return ge::GRAPH_FAILED);
85 }
86 
87 int64_t dim0Size = (xShape->GetDim(0) / (static_cast<int64_t>(*blockSize) * 2) + groupIdxDim0); // 不带起始0
88 // dynamic -2 or -1 (groupIdxShape), dynamic -1 (input x)
89 if (Ops::Base::IsUnknownRank(*groupIdxShape) || groupIdxDim0 == -1|| xShape->GetDim(0) == -1) {
90 dim0Size = -1;
91 }
92 
93 scaleShape->SetDimNum(SCALE_DIM_NUM);
94 scaleShape->SetDim(0, dim0Size);
95 scaleShape->SetDim(1, (xShape->GetDim(1) == -1) ? -1 : xShape->GetDim(1));
96 scaleShape->SetDim(2, 2); // mxscale's third dimensions only support 2
97 OP_LOGD(context->GetNodeName(), "mxscale shape is :%s after infershape.", Shape2String(*scaleShape).c_str());
98 OP_LOGD(context->GetNodeName(), "End to do InferShapeForGroupedDynamicMxQuant");
99 return ge::GRAPH_SUCCESS;
100}
101 
102static ge::graphStatus InferDataTypeForGroupedDynamicMxQuant(gert::InferDataTypeContext *context) {
103 OP_LOGD(context->GetNodeName(), "Begin to do InferDataTypeForGroupedDynamicMxQuant");
104 auto attrsPtr = context->GetAttrs();
105 OP_CHECK_NULL_WITH_CONTEXT(context, attrsPtr);
106 ge::DataType yDtype = ge::DT_FLOAT8_E5M2;
107 const int32_t *pDstDtype = attrsPtr->GetAttrPointer<int32_t>(INDEX_ATTR_DST_TYPE);
108 if (pDstDtype != nullptr) {
109 int32_t dstDtype = *pDstDtype;
110 OP_CHECK_IF(dstDtype != DTYPE_FLOAT8_E5M2 && dstDtype != DTYPE_FLOAT8_E4M3FN,
111 OP_LOGE(context->GetNodeName(),
112 "attr dst_type only support 35(FLOAT8_E5M2) and 36(FLOAT8_E4M3FN)"),
113 return ge::GRAPH_FAILED);
114 yDtype = static_cast<ge::DataType>(dstDtype);
115 }
116 context->SetOutputDataType(0, yDtype);
117 context->SetOutputDataType(1, ge::DT_FLOAT8_E8M0);
118 OP_LOGD(context->GetNodeName(), "End to do InferDataTypeForGroupedDynamicMxQuant");
119 return ge::GRAPH_SUCCESS;
120}
121 
122IMPL_OP_INFERSHAPE(GroupedDynamicMxQuant)
123 .InferShape(InferShapeForGroupedDynamicMxQuant)
124 .InferDataType(InferDataTypeForGroupedDynamicMxQuant);
125} // namespace ops
Aquant/grouped_dynamic_mx_quant/op_host/op_api/aclnn_grouped_dynamic_mx_quant.h+56-0
@@ -0,0 +1,56 @@
1/**
2 * Copyright (c) 2025 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#ifndef ACLNN_GROUPED_DYNAMIC_MX_QUANT_H_
11#define ACLNN_GROUPED_DYNAMIC_MX_QUANT_H_
12 
13#include "aclnn/acl_meta.h"
14 
15#ifdef __cplusplus
16extern "C" {
17#endif
18 
19/**
20 * @brief aclnnGroupedDynamicMxQuant的第一段接口,根据具体的计算流程,计算workspace大小。
21 * @domain aclnn_ops_infer
22 *
23 * @param [in] x: 待进行GroupedDynamicMxQuant计算的入参。npu device侧的aclTensor,
24 * 数据类型支持float16, bfloat16, 数据格式支持ND,支持非连续的Tensor。
25 * @param [in] groupIndex: npu device侧的aclTensor,数据类型支持int32
26 * @param [in] roundMode: host侧的aclScalar,数据类型string,仅支持 "rint"
27 * @param [in] dstType: host侧的aclScalar, 数据类型int, 输入范围为{35, 36},分别对应输出y的数据类型为{35: FLOAT8_E5M2, 36: FLOAT8_E4M3FN}
28 * @param [in] blocksize: host侧的aclScalar, 数据类型int,仅支持 "32"
29 * @param [in] y: GroupedDynamicMxQuant计算的出参。npu device侧的aclTensor,
30 * 数据类型支持float8_e4m3fn, float8_e5m2, 数据格式支持ND,支持非连续的Tensor。
31 * @param [in] mxscale: GroupedDynamicMxQuant计算的出参。npu device侧的aclTensor,
32 * 数据类型支持float8_e8m0, 数据格式支持ND,不支持非连续的Tensor。
33 * @param [out] workspaceSize: 返回用户需要在npu device侧申请的workspace大小。
34 * @param [out] executor: 返回op执行器,包含算子计算流程。
35 * @return aclnnStatus: 返回状态码。
36 */
37__attribute__((visibility("default"))) aclnnStatus aclnnGroupedDynamicMxQuantGetWorkspaceSize(
38 const aclTensor* x, const aclTensor* groupIndex, const char* roundMode, int64_t dstType, int64_t blocksize, const aclTensor* y, const aclTensor* mxscale,
39 uint64_t* workspaceSize, aclOpExecutor** executor);
40 
41/**
42 * @brief aclnnGroupedDynamicMxQuant的第二段接口,用于执行计算。
43 * @param [in] workspace: 在npu device侧申请的workspace内存起址。
44 * @param [in] workspaceSize: 在npu device侧申请的workspace大小,由第一段接口aclnnGroupQuantGetWorkspaceSize获取。
45 * @param [in] executor: op执行器,包含了算子计算流程。
46 * @param [in] stream: acl stream流。
47 * @return aclnnStatus: 返回状态码。
48 */
49__attribute__((visibility("default"))) aclnnStatus aclnnGroupedDynamicMxQuant(void* workspace, uint64_t workspaceSize,
50 aclOpExecutor* executor, aclrtStream stream);
51 
52#ifdef __cplusplus
53}
54#endif
55 
56#endif // ACLNN_GROUPED_DYNAMIC_MX_QUANT_H_
Aquant/grouped_dynamic_mx_quant/op_host/op_api/grouped_dynamic_mx_quant.h+22-0
@@ -0,0 +1,22 @@
1/**
2 * Copyright (c) 2025 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#ifndef OP_API_INC_LEVEL0_GROUPED_DYNAMIC_MX_QUANT_QUANT_H_
11#define OP_API_INC_LEVEL0_GROUPED_DYNAMIC_MX_QUANT_QUANT_H_
12 
13#include <string>
14#include "opdev/op_executor.h"
15 
16namespace l0op {
17std::tuple<aclTensor*, aclTensor*> GroupedDynamicMxQuant(const aclTensor *x, const aclTensor *groupIndex,
18 const char *roundMode, int64_t dstType,
19 int64_t blocksize, aclOpExecutor *executor);
20} // l0op
21 
22#endif // OP_API_INC_LEVEL0_GROUP_QUANT_H_
Aquant/grouped_dynamic_mx_quant/op_kernel/arch35/grouped_dynamic_mx_quant_common.h+44-0
@@ -0,0 +1,44 @@
1/**
2 * Copyright (c) 2025 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 grouped_dynamic_mx_quant_common.h
13 * \brief
14 */
15 
16#ifndef GRROUPED_DYNAMIC_MX_QUANT_COMMON_H
17#define GRROUPED_DYNAMIC_MX_QUANT_COMMON_H
18 
19#include "kernel_operator.h"
20namespace GroupedDynamicMxQuant {
21template<typename Tp, Tp v>
22struct IntegralConstant {
23 static constexpr Tp value = v;
24};
25using trueType = IntegralConstant<bool, true>;
26using falseType = IntegralConstant<bool, false>;
27template <typename, typename>
28struct IsSame : public falseType {
29};
30template <typename Tp>
31struct IsSame<Tp, Tp> : public trueType {
32};
33 
34constexpr int64_t DB_BUFFER = 2;
35constexpr uint16_t NAN_CUSTOMIZATION = 0x7f81;
36constexpr uint16_t MAX_EXP_FOR_BF16 = 0x7f80;
37constexpr uint16_t MAX_EXP_FOR_FP8 = 0x00ff;
38constexpr uint16_t SPECIAL_EXP_THRESHOLD = 0x0040;
39constexpr int16_t SHR_NUM_FOR_BF16 = 7;
40constexpr uint16_t BF16_EXP_BIAS = 0x7f00;
41constexpr uint16_t FP8_E4M3_MAX_EXP = 0x0400; // elem_emax右移7位(BF16E8M7)
42constexpr uint16_t FP8_E5M2_MAX_EXP = 0x0780;
43}
44#endif // GRROUPED_DYNAMIC_MX_QUANT_COMMON_H
Aquant/grouped_dynamic_mx_quant/op_kernel/arch35/grouped_dynamic_mx_quant_not_tail_axis_fp8.h+462-0文件内容审核中,请稍后刷新重试
Aquant/grouped_dynamic_mx_quant/op_kernel/grouped_dynamic_mx_quant.cpp+61-0文件内容审核中,请稍后刷新重试
Rindex/index_fill_d/tests/ut/graph_plugin/CMakeLists.txtquant/grouped_dynamic_mx_quant/tests/CMakeLists.txt+5-8
@@ -1,18 +1,15 @@
1# ----------------------------------------------------------------------------1# -----------------------------------------------------------------------------------------------------------
2# Copyright (c) 2025 Huawei Technologies Co., Ltd.2# Copyright (c) 2025 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.
6# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8# See LICENSE in the root of the software repository for the full text of the License.
9# ----------------------------------------------------------------------------9# -----------------------------------------------------------------------------------------------------------
10 
11file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)10file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
12message(STATUS "=== Debug: CURRENT_SOURCE_DIRS =${CURRENT_SOURCE_DIRS} ")
13foreach(SUB_DIR ${CURRENT_DIRS})11foreach(SUB_DIR ${CURRENT_DIRS})
14 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")12 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")
15 add_subdirectory(${SUB_DIR})13 add_subdirectory(${SUB_DIR})
16 endif()14 endif()
17endforeach()15endforeach()
18 
Rindex/index_put_v2/tests/ut/graph_plugin/CMakeLists.txtquant/grouped_dynamic_mx_quant/tests/ut/CMakeLists.txt+5-8
@@ -1,18 +1,15 @@
1#1# -----------------------------------------------------------------------------------------------------------
2# Copyright (c) 2025 Huawei Technologies Co., Ltd.2# Copyright (c) 2025 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.
6# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 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.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.8# See LICENSE in the root of the software repository for the full text of the License.
9#/9# -----------------------------------------------------------------------------------------------------------
10 
11file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)10file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
12message(STATUS "=== Debug: CURRENT_SOURCE_DIRS =${CURRENT_SOURCE_DIRS} ")
13foreach(SUB_DIR ${CURRENT_DIRS})11foreach(SUB_DIR ${CURRENT_DIRS})
14 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")12 if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")
15 add_subdirectory(${SUB_DIR})13 add_subdirectory(${SUB_DIR})
16 endif()14 endif()
17endforeach()15endforeach()
18 
Aquant/grouped_dynamic_mx_quant/tests/ut/op_api/CMakeLists.txt+14-0
@@ -0,0 +1,14 @@
1# -----------------------------------------------------------------------------------------------------------
2# Copyright (c) 2025 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 
11file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
12if(UT_TEST_ALL OR OP_API_UT)
13 add_modules_ut_sources(HOSTNAME ${OP_API_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})
14endif()
Aquant/grouped_dynamic_mx_quant/tests/ut/op_api/test_aclnn_grouped_dynamic_mx_quant.cpp+344-0文件内容审核中,请稍后刷新重试
Aquant/grouped_dynamic_mx_quant/tests/ut/op_host/CMakeLists.txt+15-0
@@ -0,0 +1,15 @@
1# -----------------------------------------------------------------------------------------------------------
2# Copyright (c) 2025 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 
11file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
12if(UT_TEST_ALL OR OP_HOST_UT)
13 add_modules_ut_sources(HOSTNAME ${OP_TILING_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})
14 add_modules_ut_sources(HOSTNAME ${OP_INFERSHAPE_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})
15endif()
Aquant/grouped_dynamic_mx_quant/tests/ut/op_host/test_grouped_dynamic_mx_quant_infershape.cpp+92-0
@@ -0,0 +1,92 @@
1/**
2 * Copyright (c) 2025 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_grouped_dynamic_mx_quant_infershape.cpp
13 * \brief
14 */
15 
16#include "ut_op_util.h"
17#include "infershape_test_util.h"
18#include <iostream>
19#include "exe_graph/runtime/storage_format.h"
20#include "exe_graph/runtime/storage_shape.h"
21#include <gtest/gtest.h>
22#include "kernel_run_context_facker.h"
23#include "register/op_impl_registry.h"
24#include "log/log.h"
25#include "platform/platform_info.h"
26#include "../../../op_graph/grouped_dynamic_mx_quant_proto.h"
27#include "ut_op_common.h"
28 
29class GroupedDynamicMxQuant : public testing::Test {
30protected:
31 static void SetUpTestCase()
32 {
33 std::cout << "GroupedDynamicMxQuant SetUp" << std::endl;
34 }
35 
36 static void TearDownTestCase()
37 {
38 std::cout << "GroupedDynamicMxQuant TearDown" << std::endl;
39 }
40};
41 
42TEST_F(GroupedDynamicMxQuant, GroupedDynamicMxQuant_infershape_case_1)
43{
44 constexpr int32_t BLOCK_SIZE = 32;
45 ge::op::GroupedDynamicMxQuant op;
46 op.UpdateInputDesc("x", create_desc({32, 128}, ge::DT_BF16));
47 op.UpdateInputDesc("group_index", create_desc({1}, ge::DT_INT32));
48 op.SetAttr("round_mode", "rint");
49 op.SetAttr("dst_type", (int64_t)ge::DT_FLOAT8_E4M3FN);
50 op.SetAttr("blocksize", BLOCK_SIZE);
51 Runtime2TestParam param{{"round_mode", "dst_type", "blocksize"}, {}, {}};
52 EXPECT_EQ(InferShapeTest(op, param), ge::GRAPH_SUCCESS);
53 auto outputY = op.GetOutputDesc(0);
54 std::vector<int64_t> expectedYShape = {32, 128};
55 EXPECT_EQ(outputY.GetShape().GetDims(), expectedYShape);
56}
57 
58TEST_F(GroupedDynamicMxQuant, GroupedDynamicMxQuant_InferDtype_case_1)
59{
60 ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl("GroupedDynamicMxQuant"), nullptr);
61 auto data_type_func = gert::OpImplRegistry::GetInstance().GetOpImpl("GroupedDynamicMxQuant")->infer_datatype;
62 
63 constexpr int32_t BLOCK_SIZE = 32;
64 if (data_type_func != nullptr) {
65 ge::DataType inDtype = ge::DT_BF16;
66 ge::DataType in2Dtype = ge::DT_INT32;
67 ge::DataType outDtype = ge::DT_FLOAT8_E4M3FN;
68 ge::DataType out2Dtype = ge::DT_FLOAT8_E8M0;
69 int64_t blockSize = 32;
70 auto context_holder = gert::InferDataTypeContextFaker()
71 .IrInputNum(2)
72 .NodeIoNum(2, 2)
73 .NodeInputTd(0, inDtype, ge::FORMAT_ND, ge::FORMAT_ND)
74 .NodeInputTd(1, in2Dtype, ge::FORMAT_ND, ge::FORMAT_ND)
75 .NodeOutputTd(0, outDtype, ge::FORMAT_ND, ge::FORMAT_ND)
76 .NodeOutputTd(1, out2Dtype, ge::FORMAT_ND, ge::FORMAT_ND)
77 .NodeAttrs({{"round_mode", Ops::NN::AnyValue::CreateFrom<string>("rint")},
78 {"dst_type", Ops::NN::AnyValue::CreateFrom((int64_t)outDtype)},
79 {"blocksize", Ops::NN::AnyValue::CreateFrom(blockSize)}})
80 .InputDataTypes({&inDtype, &in2Dtype})
81 .OutputDataTypes({&outDtype, &out2Dtype})
82 .Build();
83 auto context = context_holder.GetContext<gert::InferDataTypeContext>();
84 EXPECT_EQ(data_type_func(context), ge::GRAPH_SUCCESS);
85 ASSERT_NE(context, nullptr);
86 
87 EXPECT_EQ(context->GetInputDataType(0), inDtype);
88 EXPECT_EQ(context->GetInputDataType(1), in2Dtype);
89 EXPECT_EQ(context->GetOutputDataType(0), outDtype);
90 EXPECT_EQ(context->GetOutputDataType(1), out2Dtype);
91 }
92}
Aquant/grouped_dynamic_mx_quant/tests/ut/op_host/test_grouped_dynamic_mx_quant_tiling.cpp+290-0
@@ -0,0 +1,290 @@
1/**
2 * Copyright (c) 2025 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_grouped_dynamic_mx_quant_tiling.cpp
13 * \brief
14 */
15#include <iostream>
16#include <fstream>
17#include <vector>
18#include <gtest/gtest.h>
19#include "log/log.h"
20#include "kernel_run_context_facker.h"
21#include "test_cube_util.h"
22#include "exe_graph/runtime/storage_format.h"
23#include "exe_graph/runtime/storage_shape.h"
24#include "platform/platform_infos_def.h"
25#include "ut_op_util.h"
26#include "../../../op_host/arch35/grouped_dynamic_mx_quant_tiling_arch35.h"
27#include "any_value.h"
28 
29 
30using namespace std;
31 
32class GroupedDynamicMxQuantTiling : public testing::Test {
33protected:
34 static void SetUpTestCase() {
35 std::cout << "GroupedDynamicMxQuantTiling SetUp" << std::endl;
36 }
37 
38 static void TearDownTestCase() {
39 std::cout << "GroupedDynamicMxQuantTiling TearDown" << std::endl;
40 }
41};
42 
43static string TilingData2Str(const gert::TilingData* tilingData)
44{
45 auto data = tilingData->GetData();
46 string result;
47 for (size_t i = 0; i < tilingData->GetDataSize(); i += sizeof(int64_t)) {
48 result += std::to_string((reinterpret_cast<const int64_t*>(tilingData->GetData())[i / sizeof(int64_t)]));
49 result += " ";
50 }
51 
52 return result;
53}
54 
55static void ExecuteTestCase(ge::DataType inDtype, ge::DataType outDtype, ge::DataType in2Dtype, ge::DataType out2Dtype, gert::StorageShape shape, gert::StorageShape groupIdxShape,
56 gert::StorageShape outShape, gert::StorageShape scaleShape, int64_t blockSize, string expectTilingData,
57 ge::graphStatus status = ge::GRAPH_SUCCESS) {
58 string compile_info_string = R"({
59 "hardware_info": {"BT_SIZE": 0, "load3d_constraints": "1",
60 "Intrinsic_fix_pipe_l0c2out": false, "Intrinsic_data_move_l12ub": true, "Intrinsic_data_move_l0c2ub": true, "Intrinsic_data_move_out2l1_nd2nz": false,
61 "UB_SIZE": 253952, "L2_SIZE": 33554432, "L1_SIZE": 524288,
62 "L0A_SIZE": 65536, "L0B_SIZE": 65536, "L0C_SIZE": 131072,
63 "CORE_NUM": 64}
64 })";
65 map<string, string> soc_infos;
66 map<string, string> aicore_spec;
67 map<string, string> intrinsics;
68 map<string, string> socversions = {{"Short_SoC_version", "Ascend910_95"}};
69 GetPlatFormInfos(compile_info_string.c_str(), soc_infos, aicore_spec, intrinsics);
70 
71 // platform info
72 fe::PlatFormInfos platform_info;
73 platform_info.Init();
74 
75 // compile info
76 optiling::GroupedDynamicMxQuantCompileInfo compile_info;
77 
78 std::string op_type("GroupedDynamicMxQuant");
79 ASSERT_NE(gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str()), nullptr);
80 auto tiling_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling;
81 auto tiling_parse_func = gert::OpImplRegistry::GetInstance().GetOpImpl(op_type.c_str())->tiling_parse;
82 
83 // tilingParseFunc simulate
84 auto kernel_holder = gert::KernelRunContextFaker()
85 .KernelIONum(2, 2)
86 .Inputs({const_cast<char *>("{}"), reinterpret_cast<void *>(&platform_info)})
87 .Outputs({&compile_info})
88 .Build();
89 
90 ASSERT_TRUE(kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->Init());
91 kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos);
92 kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec);
93 kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore");
94 kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics);
95 kernel_holder.GetContext<gert::TilingParseContext>()->GetPlatformInfo()->SetPlatformRes("version", socversions);
96 ASSERT_EQ(tiling_parse_func(kernel_holder.GetContext<gert::KernelContext>()), ge::GRAPH_SUCCESS);
97 // tilingFunc simulate
98 auto param = gert::TilingData::CreateCap(4096);
99 auto workspace_size_holer = gert::ContinuousVector::Create<size_t>(4096);
100 auto ws_size = reinterpret_cast<gert::ContinuousVector *>(workspace_size_holer.get());
101 ASSERT_NE(param, nullptr);
102 auto holder = gert::TilingContextFaker()
103 .NodeIoNum(2, 2)
104 .IrInstanceNum({1, 1})
105 .InputShapes({&shape, &groupIdxShape})
106 .OutputShapes({&outShape, &scaleShape})
107 .CompileInfo(&compile_info)
108 .PlatformInfo(reinterpret_cast<char *>(&platform_info))
109 .NodeInputTd(0, inDtype, ge::FORMAT_ND, ge::FORMAT_ND)
110 .NodeInputTd(1, in2Dtype, ge::FORMAT_ND, ge::FORMAT_ND)
111 .NodeOutputTd(0, outDtype, ge::FORMAT_ND, ge::FORMAT_ND)
112 .NodeOutputTd(1, out2Dtype, ge::FORMAT_ND, ge::FORMAT_ND)
113 .NodeAttrs({{"round_mode", Ops::NN::AnyValue::CreateFrom<string>("rint")},
114 {"dst_type", Ops::NN::AnyValue::CreateFrom((int64_t)outDtype)},
115 {"blocksize", Ops::NN::AnyValue::CreateFrom(blockSize)}})
116 .TilingData(param.get())
117 .Workspace(ws_size)
118 .Build();
119 
120 gert::TilingContext* tiling_context = holder.GetContext<gert::TilingContext>();
121 ASSERT_NE(tiling_context->GetPlatformInfo(), nullptr);
122 holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("SoCInfo", soc_infos);
123 holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreSpec", aicore_spec);
124 holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetCoreNumByCoreType("AICore");
125 holder.GetContext<gert::TilingContext>()->GetPlatformInfo()->SetPlatformRes("AICoreintrinsicDtypeMap", intrinsics);
126 tiling_context->GetPlatformInfo()->SetPlatformRes("version", socversions);
127 
128 // workspaces nullptr return failed
129 EXPECT_EQ(tiling_func(tiling_context), status);
130 if (status == ge::GRAPH_FAILED) {
131 return;
132 }
133 // todo check tiling result
134 auto tiling_key = tiling_context->GetTilingKey();
135 auto block_dim = tiling_context->GetBlockDim();
136 auto tiling_data_result = TilingData2Str(tiling_context->GetRawTilingData());
137 EXPECT_EQ(tiling_data_result, expectTilingData);
138}
139 
140TEST_F(GroupedDynamicMxQuantTiling, GroupedDynamicMxQuant_tiling_ascendc_bfloat16_fp8e4m3fn) {
141 gert::StorageShape shape = {{32, 128}, {32, 128}};
142 gert::StorageShape groupIdxShape = {{1}, {1}};
143 gert::StorageShape scaleShape = {{1, 128, 2}, {1, 128, 2}};
144 int64_t blockSize = 32;
145 string expectTilingData = "64 1 1 1 1 128 128 128 32 32 128 ";
146 
147 ExecuteTestCase(ge::DT_BF16, ge::DT_FLOAT8_E4M3FN, ge::DT_INT32, ge::DT_FLOAT8_E8M0, shape, groupIdxShape, shape, scaleShape, blockSize, expectTilingData);
148}
149 
150TEST_F(GroupedDynamicMxQuantTiling, GroupedDynamicMxQuant_tiling_ascendc_float16_fp8e4m3fn) {
151 gert::StorageShape shape = {{32, 128}, {32, 128}};
152 gert::StorageShape groupIdxShape = {{1}, {1}};
153 gert::StorageShape scaleShape = {{1, 128, 2}, {1, 128, 2}};
154 int64_t blockSize = 32;
155 string expectTilingData = "64 1 1 1 1 128 128 128 32 32 128 ";
156 
157 ExecuteTestCase(ge::DT_FLOAT16, ge::DT_FLOAT8_E4M3FN, ge::DT_INT32, ge::DT_FLOAT8_E8M0, shape, groupIdxShape, shape, scaleShape, blockSize, expectTilingData);
158}
159 
160TEST_F(GroupedDynamicMxQuantTiling, GroupedDynamicMxQuant_tiling_ascendc_bfloat16_fp8e5m2) {
161 gert::StorageShape shape = {{32, 128}, {32, 128}};
162 gert::StorageShape groupIdxShape = {{1}, {1}};
163 gert::StorageShape scaleShape = {{1, 128, 2}, {1, 128, 2}};
164 int64_t blockSize = 32;
165 string expectTilingData = "64 1 1 1 1 128 128 128 32 32 128 ";
166 
167 ExecuteTestCase(ge::DT_BF16, ge::DT_FLOAT8_E5M2, ge::DT_INT32, ge::DT_FLOAT8_E8M0, shape, groupIdxShape, shape, scaleShape, blockSize, expectTilingData);
168}
169 
170TEST_F(GroupedDynamicMxQuantTiling, GroupedDynamicMxQuant_tiling_ascendc_float16_fp8e5m2) {
171 gert::StorageShape shape = {{32, 128}, {32, 128}};
172 gert::StorageShape groupIdxShape = {{1}, {1}};
173 gert::StorageShape scaleShape = {{1, 128, 2}, {1, 128, 2}};
174 int64_t blockSize = 32;
175 string expectTilingData = "64 1 1 1 1 128 128 128 32 32 128 ";
176 
177 ExecuteTestCase(ge::DT_FLOAT16, ge::DT_FLOAT8_E5M2, ge::DT_INT32, ge::DT_FLOAT8_E8M0, shape, groupIdxShape, shape, scaleShape, blockSize, expectTilingData);
178}
179 
180TEST_F(GroupedDynamicMxQuantTiling, GroupedDynamicMxQuant_tiling_ascendc_error_inDtype) {
181 gert::StorageShape shape = {{32, 128}, {32, 128}};
182 gert::StorageShape groupIdxShape = {{1}, {1}};
183 gert::StorageShape scaleShape = {{1, 128, 2}, {1, 128, 2}};
184 int64_t blockSize = 32;
185 string expectTilingData = "";
186 
187 ExecuteTestCase(ge::DT_FLOAT, ge::DT_FLOAT8_E5M2, ge::DT_INT32, ge::DT_FLOAT8_E8M0, shape, groupIdxShape, shape, scaleShape, blockSize,
188 expectTilingData, ge::GRAPH_FAILED);
189}
190 
191TEST_F(GroupedDynamicMxQuantTiling, GroupedDynamicMxQuant_tiling_ascendc_error_inDtype2) {
192 gert::StorageShape shape = {{32, 128}, {32, 128}};
193 gert::StorageShape groupIdxShape = {{1}, {1}};
194 gert::StorageShape scaleShape = {{1, 128, 2}, {1, 128, 2}};
195 int64_t blockSize = 32;
196 string expectTilingData = "";
197 
198 ExecuteTestCase(ge::DT_FLOAT16, ge::DT_FLOAT8_E5M2, ge::DT_INT16, ge::DT_FLOAT8_E8M0, shape, groupIdxShape, shape, scaleShape, blockSize,
199 expectTilingData, ge::GRAPH_FAILED);
200}
201 
202TEST_F(GroupedDynamicMxQuantTiling, GroupedDynamicMxQuant_tiling_ascendc_error_outDtype) {
203 gert::StorageShape shape = {{32, 128}, {32, 128}};
204 gert::StorageShape groupIdxShape = {{1}, {1}};
205 gert::StorageShape scaleShape = {{1, 128, 2}, {1, 128, 2}};
206 int64_t blockSize = 32;
207 string expectTilingData = "";
208 
209 ExecuteTestCase(ge::DT_FLOAT16, ge::DT_FLOAT16, ge::DT_INT32, ge::DT_FLOAT8_E8M0, shape, groupIdxShape, shape, scaleShape, blockSize, expectTilingData,
210 ge::GRAPH_FAILED);
211}
212 
213TEST_F(GroupedDynamicMxQuantTiling, GroupedDynamicMxQuant_tiling_ascendc_error_outDtype2) {
214 gert::StorageShape shape = {{32, 128}, {32, 128}};
215 gert::StorageShape groupIdxShape = {{1}, {1}};
216 gert::StorageShape scaleShape = {{1, 128, 2}, {1, 128, 2}};
217 int64_t blockSize = 32;
218 string expectTilingData = "";
219 
220 ExecuteTestCase(ge::DT_FLOAT16, ge::DT_FLOAT8_E5M2, ge::DT_INT32, ge::DT_FLOAT16, shape, groupIdxShape, shape, scaleShape, blockSize, expectTilingData,
221 ge::GRAPH_FAILED);
222}
223 
224TEST_F(GroupedDynamicMxQuantTiling, GroupedDynamicMxQuant_tiling_ascendc_error_blockSize) {
225 gert::StorageShape shape = {{32, 128}, {32, 128}};
226 gert::StorageShape groupIdxShape = {{1}, {1}};
227 gert::StorageShape scaleShape = {{1, 128, 2}, {1, 128, 2}};
228 int64_t blockSize = 64;
229 string expectTilingData = "";
230 
231 ExecuteTestCase(ge::DT_FLOAT16, ge::DT_FLOAT8_E5M2, ge::DT_INT32, ge::DT_FLOAT8_E8M0, shape, groupIdxShape, shape, scaleShape, blockSize, expectTilingData,
232 ge::GRAPH_FAILED);
233}
234 
235TEST_F(GroupedDynamicMxQuantTiling, GroupedDynamicMxQuant_tiling_ascendc_error_scale_shape) {
236 gert::StorageShape shape = {{32, 128}, {32, 128}};
237 gert::StorageShape groupIdxShape = {{1}, {1}};
238 gert::StorageShape scaleShape = {{1, 128, 3}, {1, 128, 3}};
239 int64_t blockSize = 32;
240 string expectTilingData = "";
241 
242 ExecuteTestCase(ge::DT_FLOAT16, ge::DT_FLOAT8_E5M2, ge::DT_INT32, ge::DT_FLOAT8_E8M0, shape, groupIdxShape, shape, scaleShape, blockSize, expectTilingData,
243 ge::GRAPH_FAILED);
244}
245 
246 
247TEST_F(GroupedDynamicMxQuantTiling, GroupedDynamicMxQuant_tiling_ascendc_error_input0_dim) {
248 gert::StorageShape shape = {{1, 32, 128}, {1, 32, 128}};
249 gert::StorageShape groupIdxShape = {{1}, {1}};
250 gert::StorageShape scaleShape = {{1, 128, 2}, {1, 128, 2}};
251 int64_t blockSize = 32;
252 string expectTilingData = "";
253 
254 ExecuteTestCase(ge::DT_FLOAT16, ge::DT_FLOAT8_E5M2, ge::DT_INT32, ge::DT_FLOAT8_E8M0, shape, groupIdxShape, shape, scaleShape, blockSize, expectTilingData,
255 ge::GRAPH_FAILED);
256}
257 
258TEST_F(GroupedDynamicMxQuantTiling, GroupedDynamicMxQuant_tiling_ascendc_error_input1_dim) {
259 gert::StorageShape shape = {{32, 128}, {32, 128}};
260 gert::StorageShape groupIdxShape = {{1, 1}, {1, 1}};
261 gert::StorageShape scaleShape = {{1, 128, 2}, {1, 128, 2}};
262 int64_t blockSize = 32;
263 string expectTilingData = "";
264 
265 ExecuteTestCase(ge::DT_FLOAT16, ge::DT_FLOAT8_E5M2, ge::DT_INT32, ge::DT_FLOAT8_E8M0, shape, groupIdxShape, shape, scaleShape, blockSize, expectTilingData,
266 ge::GRAPH_FAILED);
267}
268 
269TEST_F(GroupedDynamicMxQuantTiling, GroupedDynamicMxQuant_tiling_ascendc_error_output0_dim) {
270 gert::StorageShape shape = {{32, 128}, {32, 128}};
271 gert::StorageShape groupIdxShape = {{1}, {1}};
272 gert::StorageShape outShape = {{1, 32, 128}, {1, 32, 128}};
273 gert::StorageShape scaleShape = {{1, 128, 2}, {1, 128, 2}};
274 int64_t blockSize = 32;
275 string expectTilingData = "";
276 
277 ExecuteTestCase(ge::DT_FLOAT16, ge::DT_FLOAT8_E5M2, ge::DT_INT32, ge::DT_FLOAT8_E8M0, shape, groupIdxShape, outShape, scaleShape, blockSize, expectTilingData,
278 ge::GRAPH_FAILED);
279}
280 
281TEST_F(GroupedDynamicMxQuantTiling, GroupedDynamicMxQuant_tiling_ascendc_error_output1_dim) {
282 gert::StorageShape shape = {{32, 128}, {32, 128}};
283 gert::StorageShape groupIdxShape = {{1}, {1}};
284 gert::StorageShape scaleShape = {{1, 256}, {1, 256}};
285 int64_t blockSize = 32;
286 string expectTilingData = "";
287 
288 ExecuteTestCase(ge::DT_FLOAT16, ge::DT_FLOAT8_E5M2, ge::DT_INT32, ge::DT_FLOAT8_E8M0, shape, groupIdxShape, shape, scaleShape, blockSize, expectTilingData,
289 ge::GRAPH_FAILED);
290}