已合并
nn仓商分资料整改 #3875
sunchun创建于 4月16日
nn仓商分资料整改 #3875
已合并
sunchun创建于 4月16日
从已删除 :nntext0416分支合入到cann/ops-nn9.0.0
共 5 个文件变更+638-777
@@ -1,20 +1,24 @@
1# aclnnScatterAdd1# aclnnScatterAdd
2 2 
3+📄 [查看源码](https://gitcode.com/cann/ops-nn/tree/master/index/scatter_elements_v2)
4+ 
3## 产品支持情况5## 产品支持情况
4 6 
5-| 产品 | 是否支持 |7+| 产品 | 是否支持 |
6-| :----------------------------------------------------------- | :------: |8+| :--- | :---: |
7-| <term>Ascend 950PR/Ascend 950DT</term> | √ |9+| <term>Ascend 950PR/Ascend 950DT</term> | √ |
8-| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |10+| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |
9-| <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term> | √ |11+| <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term> | √ |
10-| <term>Atlas 200I/500 A2 推理产品</term> | × |12+| <term>Atlas 200I/500 A2 推理产品</term> | × |
11-| <term>Atlas 推理系列产品</term> | × |13+| <term>Atlas 推理系列产品</term> | × |
12-| <term>Atlas 训练系列产品</term> | × |14+| <term>Atlas 训练系列产品</term> | × |
13 15 
14## 功能说明16## 功能说明
15 17 
16-- 算子功能:将src tensor中的值按指定的轴方向和index tensor中的位置关系逐个填入self tensor中,若有多于一个src值被填入到self的同一位置,那么这些值将会在这一位置上进行累加。18+- 接口功能:将src tensor中的值按指定的轴方向和index tensor中的位置关系逐个填入self tensor中,若有多于一个src值被填入到self的同一位置,那么这些值将会在这一位置上进行累加。
17- 对于一个3D tensor, self会按照如下的规则进行更新:19+ 
20+ 用例:
21+ 对于一个3D tensor,self会按照如下的规则进行更新:
18 22 
19 ```23 ```
20 self[index[i][j][k]][j][k] += src[i][j][k] # 如果 dim == 024 self[index[i][j][k]][j][k] += src[i][j][k] # 如果 dim == 0
@@ -23,87 +27,234 @@
23 ```27 ```
24 28 
25 在计算时需要满足以下要求:29 在计算时需要满足以下要求:
26- - self, index和src的维度数量必须相同30+ - self、index和src的维度数量必须相同。
27- - 对于每一个维度d, 有index.size(d) <= src.size(d)31+ - 对于每一个维度d,有index.size(d) <= src.size(d)。
28- - 对于每一个维度d, 如果有d != dim, 有index.size(d) <= self.size(d)32+ - 对于每一个维度d,如果有d != dim,有index.size(d) <= self.size(d)。
29- - dim取值范围为[-self.dim(), self.dim() - 1]33+ - dim取值范围为[-self.dim(), self.dim() - 1]。
30-- 用例:34+ 
31- 35+- 示例:
32- 输入tensor $self = \begin{bmatrix} [1&2&3] \\ [4&5&6] \\ [7&8&9] \end{bmatrix}$,36+ 
33- 索引tensor $index = \begin{bmatrix} [0&2&1] \\ [0&0&1] \end{bmatrix}$, dim = 1,37+ 输入tensor $self = \begin{bmatrix} [1&2&3] \\ [4&5&6] \\ [7&8&9] \end{bmatrix}$,
38+ 索引tensor $index = \begin{bmatrix} [0&2&1] \\ [0&0&1] \end{bmatrix}$, dim = 1,
34 源tensor $src = \begin{bmatrix} [10&11&12] \\ [13&14&15] \end{bmatrix}$,39 源tensor $src = \begin{bmatrix} [10&11&12] \\ [13&14&15] \end{bmatrix}$,
35 输出tensor $output = \begin{bmatrix} [11&14&14] \\ [31&20&6] \\ [7&8&9] \end{bmatrix}$40 输出tensor $output = \begin{bmatrix} [11&14&14] \\ [31&20&6] \\ [7&8&9] \end{bmatrix}$
36- 41+ 
37 dim = 1 表示scatter_add根据$index$在tensor的列上进行累加。42 dim = 1 表示scatter_add根据$index$在tensor的列上进行累加。
38- 43+ 
39- $output[0][0] = self[0][0] + src[0][0]$ = 1 + 10,44+ $output[0][0] = self[0][0] + src[0][0]$ = 1 + 10,
40- 45+ 
41- $output[0][1] = self[0][1] + src[0][2]$ = 2 + 12,46+ $output[0][1] = self[0][1] + src[0][2]$ = 2 + 12,
42- 47+ 
43- $output[0][2] = self[0][2] + src[0][1]$ = 3 + 11,48+ $output[0][2] = self[0][2] + src[0][1]$ = 3 + 11,
44- 49+ 
45- $output[1][0] = self[1][0] + src[1][0] + src[1][1]$ = 4 + 13 + 14,50+ $output[1][0] = self[1][0] + src[1][0] + src[1][1]$ = 4 + 13 + 14,
46- 51+ 
47- $output[1][1] = self[1][1] + src[1][2]$ = 5 + 15,52+ $output[1][1] = self[1][1] + src[1][2]$ = 5 + 15,
48- 53+ 
49- $output[1][2] = self[1][2]$ = 6,54+ $output[1][2] = self[1][2]$ = 6,
50- 55+ 
51- $output[2][0] = self[2][0]$ = 7,56+ $output[2][0] = self[2][0]$ = 7,
52- 57+ 
53- $output[2][1] = self[2][1]$ = 8,58+ $output[2][1] = self[2][1]$ = 8,
54- 59+ 
55- $output[2][2] = self[2][2]$ = 9.60+ $output[2][2] = self[2][2]$ = 9。
56- 61+ 
57 其中,$self$、$index$、$src$的维度数量均为2,$index$每个维度大小{2,3}都不大于$src$的对应维度大小{2,3},在dim != 1的维度上(dim = 0),$index$的维度大小{2}不大于$self$的对应维度大小{3},$index$中的最大值{2},小于$self$在dim = 1维度的大小{3}。62 其中,$self$、$index$、$src$的维度数量均为2,$index$每个维度大小{2,3}都不大于$src$的对应维度大小{2,3},在dim != 1的维度上(dim = 0),$index$的维度大小{2}不大于$self$的对应维度大小{3},$index$中的最大值{2},小于$self$在dim = 1维度的大小{3}。
58 63 
59## 函数原型64## 函数原型
60 65 
61每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用“aclnnScatterAddGetWorkspaceSize”接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用“aclnnScatterAdd”接口执行计算。66每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用“aclnnScatterAddGetWorkspaceSize”接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用“aclnnScatterAdd”接口执行计算。
62 67 
63-* `aclnnStatus aclnnScatterAddGetWorkspaceSize(const aclTensor* self, int64_t dim, const aclTensor* index, const aclTensor* src, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor)`68+```Cpp
64-* `aclnnStatus aclnnScatterAdd(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, const aclrtStream stream)`69+aclnnStatus aclnnScatterAddGetWorkspaceSize(
70+ const aclTensor* self,
71+ int64_t dim,
72+ const aclTensor* index,
73+ const aclTensor* src,
74+ aclTensor* out,
75+ uint64_t* workspaceSize,
76+ aclOpExecutor** executor)
77+```
78+ 
79+```Cpp
80+aclnnStatus aclnnScatterAdd(
81+ void* workspace,
82+ uint64_t workspaceSize,
83+ aclOpExecutor* executor,
84+ const aclrtStream stream)
85+```
65 86 
66## aclnnScatterAddGetWorkspaceSize87## aclnnScatterAddGetWorkspaceSize
67 88 
68- **参数说明:**89- **参数说明:**
69 90 
70- - self(aclTensor*,计算输入):公式中的输入`self`,Device侧的aclTensor。scatter的目标张量,shape支持0-8维,且维度数量需要与index和src相同。数据类型与src的数据类型一致。支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND。91+ <table style="undefined;table-layout: fixed; width: 1550px"><colgroup>
71- - <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>、<term>Ascend 950PR/Ascend 950DT</term>:数据类型支持BFLOAT16、FLOAT16、FLOAT32、DOUBLE、INT64、INT32、INT16、INT8、UINT8、BOOL、COMPLEX64、COMPLEX128。92+ <col style="width: 180px">
72- - dim(int64_t, 计算输入):计算公式中的输入`dim`,数据类型为INT64。93+ <col style="width: 120px">
73- 94+ <col style="width: 280px">
74- - index(aclTensor*,计算输入):公式中的输入`index`,Device侧的aclTensor。数据类型支持INT32、INT64。index维度数量需要与src相同。支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND。95+ <col style="width: 320px">
75- - <term>Ascend 950PR/Ascend 950DT</term>:当dim轴上index值存在重复时,结果将是不确定的。若开启了确定性计算,可保证结果的确定性。96+ <col style="width: 250px">
76- - src(aclTensor*,计算输入):公式中的输入`src`,Device侧的aclTensor。源张量,src维度数量需要与index相同。数据类型与self的数据类型一致。[数据格式](../../../docs/zh/context/数据格式.md)支持ND。97+ <col style="width: 120px">
77- - <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>、<term>Ascend 950PR/Ascend 950DT</term>:数据类型支持BFLOAT16、FLOAT16、FLOAT32、DOUBLE、INT64、INT32、INT16、INT8、UINT8、BOOL、COMPLEX64、COMPLEX128。98+ <col style="width: 140px">
78- - out(aclTensor*,计算输出):公式中的`output`,Device侧的aclTensor。shape需要与self一致。数据类型与self的数据类型一致。[数据格式](../../../docs/zh/context/数据格式.md)支持ND。99+ <col style="width: 140px">
79- - <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>、<term>Ascend 950PR/Ascend 950DT</term>:数据类型支持BFLOAT16、FLOAT16、FLOAT32、DOUBLE、INT64、INT32、INT16、INT8、UINT8、BOOL、COMPLEX64、COMPLEX128。100+ </colgroup>
80- - workspaceSize(uint64_t* 出参):返回需要在Device侧申请的workspace大小。101+ <thead>
81- 102+ <tr>
82- - executor(aclOpExecutor**,出参):返回op执行器,包含了算子计算流程。103+ <th>参数名</th>
104+ <th>输入/输出</th>
105+ <th>描述</th>
106+ <th>使用说明</th>
107+ <th>数据类型</th>
108+ <th>数据格式</th>
109+ <th>维度(shape)</th>
110+ <th>非连续Tensor</th>
111+ </tr></thead>
112+ <tbody>
113+ <tr>
114+ <td>self(aclTensor*)</td>
115+ <td>输入</td>
116+ <td>公式中的输入`self`,scatter的目标张量。</td>
117+ <td>维度数量需要与index和src相同。<br>数据类型与src的数据类型一致。</td>
118+ <td>BFLOAT16、FLOAT16、FLOAT32、DOUBLE、INT64、INT32、INT16、INT8、UINT8、BOOL、COMPLEX64、COMPLEX128</td>
119+ <td>ND</td>
120+ <td>0-8</td>
121+ <td>√</td>
122+ </tr>
123+ <tr>
124+ <td>dim(int64_t)</td>
125+ <td>输入</td>
126+ <td>计算公式中的输入`dim`。</td>
127+ <td>-</td>
128+ <td>-</td>
129+ <td>-</td>
130+ <td>-</td>
131+ <td>-</td>
132+ </tr>
133+ <tr>
134+ <td>index(aclTensor*)</td>
135+ <td>输入</td>
136+ <td>公式中的输入`index`。</td>
137+ <td>维度数量需要与src相同。</td>
138+ <td>INT32、INT64</td>
139+ <td>ND</td>
140+ <td>-</td>
141+ <td>√</td>
142+ </tr>
143+ <tr>
144+ <td>src(aclTensor*)</td>
145+ <td>输入</td>
146+ <td>公式中的输入`src`,源张量。</td>
147+ <td>维度数量需要与index相同。<br>数据类型与self的数据类型一致。</td>
148+ <td>BFLOAT16、FLOAT16、FLOAT32、DOUBLE、INT64、INT32、INT16、INT8、UINT8、BOOL、COMPLEX64、COMPLEX128</td>
149+ <td>ND</td>
150+ <td>-</td>
151+ <td>×</td>
152+ </tr>
153+ <tr>
154+ <td>out(aclTensor*)</td>
155+ <td>输出</td>
156+ <td>公式中的`output`。</td>
157+ <td>shape需要与self一致。<br>数据类型与self的数据类型一致。</td>
158+ <td>BFLOAT16、FLOAT16、FLOAT32、DOUBLE、INT64、INT32、INT16、INT8、UINT8、BOOL、COMPLEX64、COMPLEX128</td>
159+ <td>ND</td>
160+ <td>-</td>
161+ <td>×</td>
162+ </tr>
163+ <tr>
164+ <td>workspaceSize(uint64_t*)</td>
165+ <td>输出</td>
166+ <td>返回需要在Device侧申请的workspace大小。</td>
167+ <td>-</td>
168+ <td>-</td>
169+ <td>-</td>
170+ <td>-</td>
171+ <td>-</td>
172+ </tr>
173+ <tr>
174+ <td>executor(aclOpExecutor**)</td>
175+ <td>输出</td>
176+ <td>返回op执行器,包含了算子计算流程。</td>
177+ <td>-</td>
178+ <td>-</td>
179+ <td>-</td>
180+ <td>-</td>
181+ <td>-</td>
182+ </tr>
183+ </tbody></table>
83 184 
84- **返回值:**185- **返回值:**
85 186 
86 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。187 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
87 188 
88- ```
89 第一段接口完成入参校验,出现以下场景时报错:189 第一段接口完成入参校验,出现以下场景时报错:
90- 返回161001(ACLNN_ERR_PARAM_NULLPTR): 1.传入的self、index、src、out是空指针。190+ 
91- 返回161002(ACLNN_ERR_PARAM_INVALID): 1.self、index、src、out的数据类型不在支持的范围之内。191+ <table style="undefined;table-layout: fixed; width: 1150px"><colgroup>
92- 2.self、out的shape不一致。192+ <col style="width: 300px">
93- 3.src、index shape不合法。193+ <col style="width: 134px">
94- ```194+ <col style="width: 716px">
195+ </colgroup>
196+ <thead>
197+ <tr>
198+ <th>返回值</th>
199+ <th>错误码</th>
200+ <th>描述</th>
201+ </tr></thead>
202+ <tbody>
203+ <tr>
204+ <td>ACLNN_ERR_PARAM_NULLPTR</td>
205+ <td>161001</td>
206+ <td>传入的self、index、src或out是空指针。</td>
207+ </tr>
208+ <tr>
209+ <td rowspan="3">ACLNN_ERR_PARAM_INVALID</td>
210+ <td rowspan="3">161002</td>
211+ <td>self、index、src或out的数据类型不在支持的范围之内。</td>
212+ </tr>
213+ <tr>
214+ <td>self和out的shape不一致。</td>
215+ </tr>
216+ <tr>
217+ <td>src或index的shape不合法。</td>
218+ </tr>
219+ </tbody></table>
95 220 
96## aclnnScatterAdd221## aclnnScatterAdd
97 222 
98- **参数说明:**223- **参数说明:**
99 224 
100- - workspace(void*,入参):在Device侧申请的workspace内存地址。225+ <table style="undefined;table-layout: fixed; width: 1100px"><colgroup>
101- 226+ <col style="width: 200px">
102- - workspaceSize(uint64_t,入参):在Device侧申请的workspace大小,由第一段接口aclnnScatterAddGetWorkspaceSize获取。227+ <col style="width: 130px">
103- 228+ <col style="width: 770px">
104- - executor(aclOpExecutor*,入参):op执行器,包含了算子计算流程。229+ </colgroup>
105- 230+ <thead>
106- - stream(aclrtStream,入参):指定执行任务的Stream。231+ <tr>
232+ <th>参数名</th>
233+ <th>输入/输出</th>
234+ <th>描述</th>
235+ </tr></thead>
236+ <tbody>
237+ <tr>
238+ <td>workspace</td>
239+ <td>输入</td>
240+ <td>在Device侧申请的workspace内存地址。</td>
241+ </tr>
242+ <tr>
243+ <td>workspaceSize</td>
244+ <td>输入</td>
245+ <td>在Device侧申请的workspace大小,由第一段接口aclnnScatterAddGetWorkspaceSize获取。</td>
246+ </tr>
247+ <tr>
248+ <td>executor</td>
249+ <td>输入</td>
250+ <td>op执行器,包含了算子计算流程。</td>
251+ </tr>
252+ <tr>
253+ <td>stream</td>
254+ <td>输入</td>
255+ <td>指定执行任务的Stream。</td>
256+ </tr>
257+ </tbody></table>
107 258 
108- **返回值:**259- **返回值:**
109 260 
@@ -111,7 +262,8 @@
111 262 
112## 约束说明263## 约束说明
113 264 
114-无265+- 确定性计算:
266+ - aclnnScatterAdd默认确定性实现。
115 267 
116## 调用示例268## 调用示例
117 269 
@@ -1,419 +0,0 @@
1-# aclnnScatterAdd
2- 
3-📄 [查看源码](https://gitcode.com/cann/ops-nn/tree/master/index/scatter_elements_v2)
4- 
5-## 产品支持情况
6- 
7-| 产品 | 是否支持 |
8-| :--- | :---: |
9-| <term>Ascend 950PR/Ascend 950DT</term> | √ |
10-| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |
11-| <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term> | √ |
12-| <term>Atlas 200I/500 A2 推理产品</term> | × |
13-| <term>Atlas 推理系列产品</term> | × |
14-| <term>Atlas 训练系列产品</term> | × |
15- 
16-## 功能说明
17- 
18-- 接口功能:将src tensor中的值按指定的轴方向和index tensor中的位置关系逐个填入self tensor中,若有多于一个src值被填入到self的同一位置,那么这些值将会在这一位置上进行累加。
19- 
20- 用例:
21- 对于一个3D tensor,self会按照如下的规则进行更新:
22- 
23- ```
24- self[index[i][j][k]][j][k] += src[i][j][k] # 如果 dim == 0
25- self[i][index[i][j][k]][k] += src[i][j][k] # 如果 dim == 1
26- self[i][j][index[i][j][k]] += src[i][j][k] # 如果 dim == 2
27- ```
28- 
29- 在计算时需要满足以下要求:
30- - self、index和src的维度数量必须相同。
31- - 对于每一个维度d,有index.size(d) <= src.size(d)。
32- - 对于每一个维度d,如果有d != dim,有index.size(d) <= self.size(d)。
33- - dim取值范围为[-self.dim(), self.dim() - 1]。
34- 
35-- 示例:
36- 
37- 输入tensor $self = \begin{bmatrix} [1&2&3] \\ [4&5&6] \\ [7&8&9] \end{bmatrix}$,
38- 索引tensor $index = \begin{bmatrix} [0&2&1] \\ [0&0&1] \end{bmatrix}$, dim = 1,
39- 源tensor $src = \begin{bmatrix} [10&11&12] \\ [13&14&15] \end{bmatrix}$,
40- 输出tensor $output = \begin{bmatrix} [11&14&14] \\ [31&20&6] \\ [7&8&9] \end{bmatrix}$
41- 
42- dim = 1 表示scatter_add根据$index$在tensor的列上进行累加。
43- 
44- $output[0][0] = self[0][0] + src[0][0]$ = 1 + 10,
45- 
46- $output[0][1] = self[0][1] + src[0][2]$ = 2 + 12,
47- 
48- $output[0][2] = self[0][2] + src[0][1]$ = 3 + 11,
49- 
50- $output[1][0] = self[1][0] + src[1][0] + src[1][1]$ = 4 + 13 + 14,
51- 
52- $output[1][1] = self[1][1] + src[1][2]$ = 5 + 15,
53- 
54- $output[1][2] = self[1][2]$ = 6,
55- 
56- $output[2][0] = self[2][0]$ = 7,
57- 
58- $output[2][1] = self[2][1]$ = 8,
59- 
60- $output[2][2] = self[2][2]$ = 9。
61- 
62- 其中,$self$、$index$、$src$的维度数量均为2,$index$每个维度大小{2,3}都不大于$src$的对应维度大小{2,3},在dim != 1的维度上(dim = 0),$index$的维度大小{2}不大于$self$的对应维度大小{3},$index$中的最大值{2},小于$self$在dim = 1维度的大小{3}。
63- 
64-## 函数原型
65- 
66-每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用“aclnnScatterAddGetWorkspaceSize”接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用“aclnnScatterAdd”接口执行计算。
67- 
68-```Cpp
69-aclnnStatus aclnnScatterAddGetWorkspaceSize(
70- const aclTensor* self,
71- int64_t dim,
72- const aclTensor* index,
73- const aclTensor* src,
74- aclTensor* out,
75- uint64_t* workspaceSize,
76- aclOpExecutor** executor)
77-```
78- 
79-```Cpp
80-aclnnStatus aclnnScatterAdd(
81- void* workspace,
82- uint64_t workspaceSize,
83- aclOpExecutor* executor,
84- const aclrtStream stream)
85-```
86- 
87-## aclnnScatterAddGetWorkspaceSize
88- 
89-- **参数说明:**
90- 
91- <table style="undefined;table-layout: fixed; width: 1550px"><colgroup>
92- <col style="width: 180px">
93- <col style="width: 120px">
94- <col style="width: 280px">
95- <col style="width: 320px">
96- <col style="width: 250px">
97- <col style="width: 120px">
98- <col style="width: 140px">
99- <col style="width: 140px">
100- </colgroup>
101- <thead>
102- <tr>
103- <th>参数名</th>
104- <th>输入/输出</th>
105- <th>描述</th>
106- <th>使用说明</th>
107- <th>数据类型</th>
108- <th>数据格式</th>
109- <th>维度(shape)</th>
110- <th>非连续Tensor</th>
111- </tr></thead>
112- <tbody>
113- <tr>
114- <td>self(aclTensor*)</td>
115- <td>输入</td>
116- <td>公式中的输入`self`,scatter的目标张量。</td>
117- <td>维度数量需要与index和src相同。<br>数据类型与src的数据类型一致。</td>
118- <td>BFLOAT16、FLOAT16、FLOAT32、DOUBLE、INT64、INT32、INT16、INT8、UINT8、BOOL、COMPLEX64、COMPLEX128</td>
119- <td>ND</td>
120- <td>0-8</td>
121- <td>√</td>
122- </tr>
123- <tr>
124- <td>dim(int64_t)</td>
125- <td>输入</td>
126- <td>计算公式中的输入`dim`。</td>
127- <td>-</td>
128- <td>-</td>
129- <td>-</td>
130- <td>-</td>
131- <td>-</td>
132- </tr>
133- <tr>
134- <td>index(aclTensor*)</td>
135- <td>输入</td>
136- <td>公式中的输入`index`。</td>
137- <td>维度数量需要与src相同。</td>
138- <td>INT32、INT64</td>
139- <td>ND</td>
140- <td>-</td>
141- <td>√</td>
142- </tr>
143- <tr>
144- <td>src(aclTensor*)</td>
145- <td>输入</td>
146- <td>公式中的输入`src`,源张量。</td>
147- <td>维度数量需要与index相同。<br>数据类型与self的数据类型一致。</td>
148- <td>BFLOAT16、FLOAT16、FLOAT32、DOUBLE、INT64、INT32、INT16、INT8、UINT8、BOOL、COMPLEX64、COMPLEX128</td>
149- <td>ND</td>
150- <td>-</td>
151- <td>×</td>
152- </tr>
153- <tr>
154- <td>out(aclTensor*)</td>
155- <td>输出</td>
156- <td>公式中的`output`。</td>
157- <td>shape需要与self一致。<br>数据类型与self的数据类型一致。</td>
158- <td>BFLOAT16、FLOAT16、FLOAT32、DOUBLE、INT64、INT32、INT16、INT8、UINT8、BOOL、COMPLEX64、COMPLEX128</td>
159- <td>ND</td>
160- <td>-</td>
161- <td>×</td>
162- </tr>
163- <tr>
164- <td>workspaceSize(uint64_t*)</td>
165- <td>输出</td>
166- <td>返回需要在Device侧申请的workspace大小。</td>
167- <td>-</td>
168- <td>-</td>
169- <td>-</td>
170- <td>-</td>
171- <td>-</td>
172- </tr>
173- <tr>
174- <td>executor(aclOpExecutor**)</td>
175- <td>输出</td>
176- <td>返回op执行器,包含了算子计算流程。</td>
177- <td>-</td>
178- <td>-</td>
179- <td>-</td>
180- <td>-</td>
181- <td>-</td>
182- </tr>
183- </tbody></table>
184- 
185-- **返回值:**
186- 
187- aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
188- 
189- 第一段接口完成入参校验,出现以下场景时报错:
190- 
191- <table style="undefined;table-layout: fixed; width: 1150px"><colgroup>
192- <col style="width: 300px">
193- <col style="width: 134px">
194- <col style="width: 716px">
195- </colgroup>
196- <thead>
197- <tr>
198- <th>返回值</th>
199- <th>错误码</th>
200- <th>描述</th>
201- </tr></thead>
202- <tbody>
203- <tr>
204- <td>ACLNN_ERR_PARAM_NULLPTR</td>
205- <td>161001</td>
206- <td>传入的self、index、src或out是空指针。</td>
207- </tr>
208- <tr>
209- <td rowspan="3">ACLNN_ERR_PARAM_INVALID</td>
210- <td rowspan="3">161002</td>
211- <td>self、index、src或out的数据类型不在支持的范围之内。</td>
212- </tr>
213- <tr>
214- <td>self和out的shape不一致。</td>
215- </tr>
216- <tr>
217- <td>src或index的shape不合法。</td>
218- </tr>
219- </tbody></table>
220- 
221-## aclnnScatterAdd
222- 
223-- **参数说明:**
224- 
225- <table style="undefined;table-layout: fixed; width: 1100px"><colgroup>
226- <col style="width: 200px">
227- <col style="width: 130px">
228- <col style="width: 770px">
229- </colgroup>
230- <thead>
231- <tr>
232- <th>参数名</th>
233- <th>输入/输出</th>
234- <th>描述</th>
235- </tr></thead>
236- <tbody>
237- <tr>
238- <td>workspace</td>
239- <td>输入</td>
240- <td>在Device侧申请的workspace内存地址。</td>
241- </tr>
242- <tr>
243- <td>workspaceSize</td>
244- <td>输入</td>
245- <td>在Device侧申请的workspace大小,由第一段接口aclnnScatterAddGetWorkspaceSize获取。</td>
246- </tr>
247- <tr>
248- <td>executor</td>
249- <td>输入</td>
250- <td>op执行器,包含了算子计算流程。</td>
251- </tr>
252- <tr>
253- <td>stream</td>
254- <td>输入</td>
255- <td>指定执行任务的Stream。</td>
256- </tr>
257- </tbody></table>
258- 
259-- **返回值:**
260- 
261- aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
262- 
263-## 约束说明
264- 
265-- 确定性计算:
266- - aclnnScatterAdd默认确定性实现。
267- 
268-## 调用示例
269- 
270-示例代码如下,仅供参考,具体编译和执行过程请参考[编译与运行样例](../../../docs/zh/context/编译与运行样例.md)。
271- 
272-```Cpp
273-#include <iostream>
274-#include <vector>
275-#include "acl/acl.h"
276-#include "aclnnop/aclnn_scatter_add.h"
277- 
278-#define CHECK_RET(cond, return_expr) \
279- do { \
280- if (!(cond)) { \
281- return_expr; \
282- } \
283- } while (0)
284- 
285-#define LOG_PRINT(message, ...) \
286- do { \
287- printf(message, ##__VA_ARGS__); \
288- } while (0)
289- 
290-int64_t GetShapeSize(const std::vector<int64_t>& shape) {
291- int64_t shapeSize = 1;
292- for (auto i : shape) {
293- shapeSize *= i;
294- }
295- return shapeSize;
296-}
297- 
298-int Init(int32_t deviceId, aclrtStream* stream) {
299- // 固定写法,资源初始化
300- auto ret = aclInit(nullptr);
301- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);
302- ret = aclrtSetDevice(deviceId);
303- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);
304- ret = aclrtCreateStream(stream);
305- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);
306- return 0;
307-}
308- 
309-template <typename T>
310-int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr,
311- aclDataType dataType, aclTensor** tensor) {
312- auto size = GetShapeSize(shape) * sizeof(T);
313- // 调用aclrtMalloc申请device侧内存
314- auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);
315- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);
316- // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上
317- ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);
318- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);
319- 
320- // 计算连续tensor的strides
321- std::vector<int64_t> strides(shape.size(), 1);
322- for (int64_t i = shape.size() - 2; i >= 0; i--) {
323- strides[i] = shape[i + 1] * strides[i + 1];
324- }
325- 
326- // 调用aclCreateTensor接口创建aclTensor
327- *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND,
328- shape.data(), shape.size(), *deviceAddr);
329- return 0;
330-}
331- 
332-int main() {
333- // 1. (固定写法)device/stream初始化,参考acl API手册
334- // 根据自己的实际device填写deviceId
335- int32_t deviceId = 0;
336- aclrtStream stream;
337- auto ret = Init(deviceId, &stream);
338- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);
339- 
340- // 2. 构造输入与输出,需要根据API的接口自定义构造
341- std::vector<int64_t> selfShape = {4, 4};
342- std::vector<int64_t> indexShape = {3, 4};
343- std::vector<int64_t> srcShape = {4, 4};
344- std::vector<int64_t> outShape = {4, 4};
345- int64_t dim = 0;
346- void* selfDeviceAddr = nullptr;
347- void* indexDeviceAddr = nullptr;
348- void* srcDeviceAddr = nullptr;
349- void* outDeviceAddr = nullptr;
350- aclTensor* self = nullptr;
351- aclTensor* index = nullptr;
352- aclTensor* src = nullptr;
353- aclTensor* out = nullptr;
354- std::vector<float> selfHostData(16, 0);
355- std::vector<int64_t> indexHostData = {0, 1, 2, 1, 0, 1, 2, 0, 2, 2, 1, 0};
356- std::vector<float> srcHostData = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
357- std::vector<float> outHostData(16, 0);
358- // 创建self aclTensor
359- ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_FLOAT, &self);
360- CHECK_RET(ret == ACL_SUCCESS, return ret);
361- // 创建index aclTensor
362- ret = CreateAclTensor(indexHostData, indexShape, &indexDeviceAddr, aclDataType::ACL_INT64, &index);
363- CHECK_RET(ret == ACL_SUCCESS, return ret);
364- // 创建src aclTensor
365- ret = CreateAclTensor(srcHostData, srcShape, &srcDeviceAddr, aclDataType::ACL_FLOAT, &src);
366- CHECK_RET(ret == ACL_SUCCESS, return ret);
367- // 创建out aclTensor
368- ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out);
369- CHECK_RET(ret == ACL_SUCCESS, return ret);
370- 
371- // 3. 调用CANN算子库API,需要修改为具体的Api名称
372- uint64_t workspaceSize = 0;
373- aclOpExecutor* executor;
374- // 调用aclnnScatterAdd第一段接口
375- ret = aclnnScatterAddGetWorkspaceSize(self, dim, index, src, out, &workspaceSize, &executor);
376- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnScatterAddGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);
377- // 根据第一段接口计算出的workspaceSize申请device内存
378- void* workspaceAddr = nullptr;
379- if (workspaceSize > 0) {
380- ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
381- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
382- }
383- // 调用aclnnScatterAdd第二段接口
384- ret = aclnnScatterAdd(workspaceAddr, workspaceSize, executor, stream);
385- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnScatterAdd failed. ERROR: %d\n", ret); return ret);
386- 
387- // 4. (固定写法)同步等待任务执行结束
388- ret = aclrtSynchronizeStream(stream);
389- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
390- 
391- // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改
392- auto size = GetShapeSize(outShape);
393- std::vector<float> resultData(size, 0);
394- ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr,
395- size * sizeof(resultData[0]), ACL_MEMCPY_DEVICE_TO_HOST);
396- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
397- for (int64_t i = 0; i < size; i++) {
398- LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]);
399- }
400- 
401- // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改
402- aclDestroyTensor(self);
403- aclDestroyTensor(index);
404- aclDestroyTensor(src);
405- aclDestroyTensor(out);
406- // 7. 释放device资源,需要根据具体API的接口定义参数
407- aclrtFree(selfDeviceAddr);
408- aclrtFree(indexDeviceAddr);
409- aclrtFree(srcDeviceAddr);
410- aclrtFree(outDeviceAddr);
411- if (workspaceSize > 0) {
412- aclrtFree(workspaceAddr);
413- }
414- aclrtDestroyStream(stream);
415- aclrtResetDevice(deviceId);
416- aclFinalize();
417- return 0;
418-}
419-```
@@ -1,231 +0,0 @@
1-# aclnnScatterNd
2- 
3-## 产品支持情况
4- 
5-| 产品 | 是否支持 |
6-| :----------------------------------------------------------- | :------: |
7-| <term>Ascend 950PR/Ascend 950DT</term> | × |
8-| <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term> | √ |
9-| <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term> | √ |
10-| <term>Atlas 200I/500 A2 推理产品</term> | × |
11-| <term>Atlas 推理系列产品</term> | × |
12-| <term>Atlas 训练系列产品</term> | × |
13- 
14-## 功能说明
15- 
16-算子功能:拷贝data的数据至out,同时在指定indices处根据updates更新out中的数据。
17- 
18-## 函数原型
19- 
20-每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用“aclnnScatterNdGetWorkspaceSize”接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用“aclnnScatterNd”接口执行计算。
21- 
22-* `aclnnStatus aclnnScatterNdGetWorkspaceSize(const aclTensor *data,const aclTensor *indices,const aclTensor *updates, aclTensor *out, uint64_t *workspaceSize, aclOpExecutor **executor)`
23-* `aclnnStatus aclnnScatterNd(void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, aclrtStream stream)`
24- 
25-## aclnnScatterNdGetWorkspaceSize
26- 
27-- **参数说明:**
28- * data(aclTensor*,计算输入):Device侧的aclTensor, 数据类型与updates、out一致,shape满足1<=rank(data)<=8。支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND。
29- - <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT16、FLOAT、BOOL、BFLOAT16
30- * indices(aclTensor*,计算输入):Device侧的aclTensor,数据类型支持INT32、INT64。indices.shape[-1] <= rank(data),且1<=rank(indices)<=8。支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND。仅支持非负索引。indices中的索引数据不支持越界。
31- 
32- * updates(aclTensor*,计算输入):Device侧的aclTensor, 数据类型与data、out一致。shape要求rank(updates)=rank(data)+rank(indices)-indices.shape[-1] -1, 且满足1<=rank(updates)<=8。支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND。
33- - <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT16、FLOAT、BOOL、BFLOAT16
34- * out(aclTensor*,计算输出):Device侧的aclTensor,数据类型与data、out一致,shape与data一致。支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND。
35- - <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT16、FLOAT、BOOL、BFLOAT16
36- * workspaceSize(uint64_t*,出参):返回需要在Device侧申请的workspace大小。
37- 
38- * executor(aclOpExecutor**,出参):返回op执行器,包含了算子计算流程。
39- 
40-- **返回值:**
41- 
42- aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
43- 
44- ```
45- 第一段接口完成入参校验,出现以下场景时报错:
46- 返回161001(ACLNN_ERR_PARAM_NULLPTR):1.传入的data、indices、updates、out中有空指针
47- 返回161002(ACLNN_ERR_PARAM_INVALID):1. 数据类型不在支持的范围之内;
48- 2. shape不满足要求:1<=rank(data)<=8, 1<=rank(indices)<=8,rank(updates)=rank(data)+rank(indices)- indices.shape[-1] -1
49- 3. shape不满足要求:1<=rank(indices)<=8, indices.shape[-1] <= rank(data)
50- 4. shape不满足要求:1<=rank(updates)<=8, updates.shape == indices.shape[:-1] + data.shape[indices.shape[-1] :]
51- 5. shape不满足要求:data.shape == out.shape
52- ```
53- 
54-## aclnnScatterNd
55- 
56-- **参数说明:**
57- * workspace(void *, 入参):在Device侧申请的workspace内存地址。
58- * workspaceSize(uint64_t, 入参):在Device侧申请的workspace大小,由第一段接口aclnnScatterNdGetWorkspaceSize获取。
59- * executor(aclOpExecutor *, 入参):op执行器,包含了算子计算流程。
60- * stream(aclrtStream, 入参):指定执行任务的Stream。
61-- **返回值:**
62- 
63- aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
64- 
65-## 约束说明
66- 
67-- 确定性计算:
68- - aclnnScatterNd默认确定性实现。
69- 
70-## 调用示例
71- 
72-示例代码如下,仅供参考,具体编译和执行过程请参考[编译与运行样例](../../../docs/zh/context/编译与运行样例.md)。
73- 
74-```Cpp
75-#include <iostream>
76-#include <vector>
77-#include "acl/acl.h"
78-#include "aclnnop/aclnn_scatter_nd.h"
79-#include "aclnn/aclnn_base.h"
80- 
81-#define CHECK_RET(cond, return_expr) \
82- do { \
83- if (!(cond)) { \
84- return_expr; \
85- } \
86- } while (0)
87- 
88-#define LOG_PRINT(message, ...) \
89- do { \
90- printf(message, ##__VA_ARGS__); \
91- } while (0)
92- 
93-int64_t GetShapeSize(const std::vector<int64_t>& shape) {
94- int64_t shapeSize = 1;
95- for (auto i : shape) {
96- shapeSize *= i;
97- }
98- return shapeSize;
99-}
100- 
101-int Init(int32_t deviceId, aclrtStream* stream) {
102- // 固定写法,资源初始化
103- 
104- auto ret = aclInit(nullptr);
105- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);
106- ret = aclrtSetDevice(deviceId);
107- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);
108- ret = aclrtCreateStream(stream);
109- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);
110- return 0;
111-}
112- 
113-template <typename T>
114-int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr,
115- aclDataType dataType, aclTensor** tensor) {
116- auto size = GetShapeSize(shape) * sizeof(T);
117- // 调用aclrtMalloc申请device侧内存
118- auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);
119- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);
120- 
121- // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上
122- ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);
123- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);
124- 
125- // 计算连续tensor的strides
126- std::vector<int64_t> strides(shape.size(), 1);
127- for (int64_t i = shape.size() - 2; i >= 0; i--) {
128- strides[i] = shape[i + 1] * strides[i + 1];
129- }
130- 
131- // 调用aclCreateTensor接口创建aclTensor
132- *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND,
133- shape.data(), shape.size(), *deviceAddr);
134- return 0;
135-}
136- 
137-int main() {
138- // 1. (固定写法)device/stream初始化, 参考acl对外接口列表
139- // 根据自己的实际device填写deviceId
140- int32_t deviceId = 0;
141- aclrtStream stream;
142- auto ret = Init(deviceId, &stream);
143- // check根据自己的需要处理
144- CHECK_RET(ret == 0, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);
145- // 2. 构造输入与输出,需要根据API的接口自定义构造
146- std::vector<int64_t> dataShape = {8};
147- std::vector<int64_t> indicesShape = {4, 1};
148- std::vector<int64_t> updatesShape = {4};
149- std::vector<int64_t> outShape = {8};
150- 
151- void* dataDeviceAddr = nullptr;
152- void* indicesDeviceAddr = nullptr;
153- void* updatesDeviceAddr = nullptr;
154- void* outDeviceAddr = nullptr;
155- aclTensor* data = nullptr;
156- aclTensor* indices = nullptr;
157- aclTensor* updates = nullptr;
158- aclTensor* out = nullptr;
159- 
160- std::vector<float> selfHostData = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0};
161- std::vector<int32_t> indicesData = {4,3,1,7};
162- std::vector<float> updatesData = {9.0, 10.0, 11.0, 12.0};
163- std::vector<float> outData = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
164- 
165- ret = CreateAclTensor(selfHostData, dataShape, &dataDeviceAddr, aclDataType::ACL_FLOAT, &data);
166- CHECK_RET(ret == ACL_SUCCESS, return ret);
167- 
168- ret = CreateAclTensor(indicesData, indicesShape, &indicesDeviceAddr, aclDataType::ACL_INT32, &indices);
169- CHECK_RET(ret == ACL_SUCCESS, return ret);
170- 
171- ret = CreateAclTensor(updatesData, updatesShape, &updatesDeviceAddr, aclDataType::ACL_FLOAT, &updates);
172- CHECK_RET(ret == ACL_SUCCESS, return ret);
173- 
174- ret = CreateAclTensor(outData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out);
175- CHECK_RET(ret == ACL_SUCCESS, return ret);
176- 
177- // 创建out aclTensor
178- // ret = CreateAclTensor(outData, outShape, &outDeviceAddr, aclDataType::ACL_INT32, &out);
179- // CHECK_RET(ret == ACL_SUCCESS, return ret);
180- 
181- // 3. 调用CANN算子库API,需要修改为具体的API
182- uint64_t workspaceSize = 0;
183- aclOpExecutor* executor;
184- // 调用aclnnAdd第一段接口
185- ret = aclnnScatterNdGetWorkspaceSize(data, indices, updates, out, &workspaceSize, &executor);
186- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnScatterNdGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);
187- // 根据第一段接口计算出的workspaceSize申请device内存
188- void* workspaceAddr = nullptr;
189- if (workspaceSize > 0) {
190- ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
191- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret;);
192- }
193- 
194- ret = aclnnScatterNd(workspaceAddr, workspaceSize, executor, stream);
195- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnScatterNd failed. ERROR: %d\n", ret); return ret);
196- // 4. (固定写法)同步等待任务执行结束
197- ret = aclrtSynchronizeStream(stream);
198- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
199- // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改
200- auto size = GetShapeSize(outShape);
201- std::vector<float> resultData(size, 0);
202- ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr, size * sizeof(float),
203- ACL_MEMCPY_DEVICE_TO_HOST);
204- CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
205- 
206- for (int64_t i = 0; i < size; i++) {
207- LOG_PRINT("result[%ld] is: %f\n", i, resultData[i]);
208- }
209- 
210- // 6. 释放aclTensor和aclScalar,需要根据具体API的接口定义修改
211- aclDestroyTensor(data);
212- aclDestroyTensor(indices);
213- aclDestroyTensor(updates);
214- aclDestroyTensor(out);
215- 
216- // 7. 释放device资源,需要根据具体API的接口定义修改
217- 
218- aclrtFree(dataDeviceAddr);
219- aclrtFree(indicesDeviceAddr);
220- aclrtFree(updatesDeviceAddr);
221- aclrtFree(outDeviceAddr);
222- if (workspaceSize > 0) {
223- aclrtFree(workspaceAddr);
224- }
225- aclrtDestroyStream(stream);
226- aclrtResetDevice(deviceId);
227- aclFinalize();
228- 
229- return 0;
230-}
231-```
@@ -19,44 +19,223 @@
19 19 
20每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用“aclnnUniqueConsecutiveGetWorkspaceSize”接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用“aclnnUniqueConsecutive”接口执行**计算。20每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用“aclnnUniqueConsecutiveGetWorkspaceSize”接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用“aclnnUniqueConsecutive”接口执行**计算。
21 21 
22-- `aclnnStatus aclnnUniqueConsecutiveGetWorkspaceSize(const aclTensor* self, bool returnInverse, bool returnCounts, int64_t dim, aclTensor* valueOut, aclTensor* inverseOut, aclTensor* countsOut, uint64_t* workspaceSize, aclOpExecutor** executor)`22+```cpp
23-- `aclnnStatus aclnnUniqueConsecutive(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream)`23+aclnnStatus aclnnUniqueConsecutiveGetWorkspaceSize(
24+ const aclTensor* self,
25+ bool returnInverse,
26+ bool returnCounts,
27+ int64_t dim,
28+ clTensor* valueOut,
29+ aclTensor* inverseOut,
30+ aclTensor* countsOut,
31+ uint64_t* workspaceSize,
32+ aclOpExecutor** executor)
33+```
34+ 
35+```cpp
36+aclnnStatus aclnnUniqueConsecutive(
37+ void* workspace,
38+ uint64_t workspaceSize,
39+ aclOpExecutor* executor,
40+ aclrtStream stream)
41+```
24 42 
25## aclnnUniqueConsecutiveGetWorkspaceSize43## aclnnUniqueConsecutiveGetWorkspaceSize
26 44 
27-* **参数说明**:45+* **参数说明**
28- - self(aclTensor*, 计算输入):Device侧的aclTensor,维度不能超过8维。[数据格式](../../../docs/zh/context/数据格式.md)支持ND。
29- - <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品/Ascend 950PR/Ascend 950DT</term>:数据类型支持FLOAT、FLOAT16、DOUBLE、INT8、INT16、INT32、INT64、UINT8、UINT16、UINT32、UINT64、COMPLEX64、COMPLEX128、BOOL、BFLOAT16。
30- - returnInverse(bool, 计算输入):表示是否返回self中各元素在valueOut中对应元素的位置下标,True时返回,False时不返回。
31- - returnCounts(bool, 计算输入):表示是否返回valueOut中各元素在self中连续重复出现的次数,True时返回,False时不返回。
32- - dim(int64_t, 计算输入):表示进行去重的维度。
33- - valueOut(aclTensor*,计算输出):第一个输出张量,返回消除连续重复元素后的结果,[数据格式](../../../docs/zh/context/数据格式.md)支持ND。
34- - <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品/Ascend 950PR/Ascend 950DT</term>:数据类型支持FLOAT、FLOAT16、DOUBLE、INT8、INT16、INT32、INT64、UINT8、UINT16、UINT32、UINT64、COMPLEX64、COMPLEX128、BOOL、BFLOAT16。
35- - inverseOut(aclTensor*,计算输出):第二个输出张量,当returnInverse为True时有意义,返回self中各元素在valueOut中对应元素的位置下标,数据类型支持INT64,[数据格式](../../../docs/zh/context/数据格式.md)支持ND。
36- - countsOut(aclTensor*,计算输出):第三个输出张量,当returnCounts为True时有意义,返回valueOut中各元素在self中连续重复出现的次数,数据类型支持INT64,[数据格式](../../../docs/zh/context/数据格式.md)支持ND。
37- - workspaceSize(uint64_t*, 出参):返回需要在Device侧申请的workspace大小。
38- - executor(aclOpExecutor**, 出参):返回op执行器,包含了算子计算流程。
39-* **返回值**:
40- aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
41 46 
42-```47+ <table style="undefined;table-layout: fixed; width: 1391px"><colgroup>
43-第一段接口完成入参校验,出现以下场景时报错:48+ <col style="width: 128px">
44-返回161001(ACLNN_ERR_PARAM_NULLPTR):1. 传入的 self 或 valueOut 或inverseOut 或 countsOut 是空指针时。49+ <col style="width: 122px">
45-返回161002(ACLNN_ERR_PARAM_INVALID):1. self 的数据类型不在支持的范围之内。50+ <col style="width: 300px">
46- 2. self 和 valueOut 的数据类型不一致。51+ <col style="width: 156px">
47- 3. inverseOut 或 countsOut 的数据类型不在支持的范围之内。52+ <col style="width: 294px">
48- 4. inverseOut 和 countsOut 的数据类型不一致。53+ <col style="width: 106px">
49-```54+ <col style="width: 136px">
55+ <col style="width: 149px">
56+ </colgroup>
57+ <thead>
58+ <tr>
59+ <th>参数名</th>
60+ <th>输入/输出</th>
61+ <th>描述</th>
62+ <th>使用说明</th>
63+ <th>数据类型</th>
64+ <th>数据格式</th>
65+ <th>维度(shape)</th>
66+ <th>非连续Tensor</th>
67+ </tr></thead>
68+ <tbody>
69+ <tr>
70+ <td>self</td>
71+ <td>输入</td>
72+ <td>-</td>
73+ <td>-</td>
74+ <td>FLOAT、FLOAT16、DOUBLE、INT8、INT16、INT32、INT64、UINT8、UINT16、UINT32、UINT64、COMPLEX64、COMPLEX128、BOOL、BFLOAT16</td>
75+ <td>ND</td>
76+ <td>≤8</td>
77+ <td>-</td>
78+ </tr>
79+ <tr>
80+ <td>returnInverse</td>
81+ <td>输入</td>
82+ <td>表示是否返回self中各元素在valueOut中对应元素的位置下标,True时返回,False时不返回。</td>
83+ <td>-</td>
84+ <td>-</td>
85+ <td>-</td>
86+ <td>-</td>
87+ <td>-</td>
88+ </tr>
89+ <tr>
90+ <td>returnCounts</td>
91+ <td>输入</td>
92+ <td>表示是否返回valueOut中各元素在self中连续重复出现的次数,True时返回,False时不返回。</td>
93+ <td>-</td>
94+ <td>-</td>
95+ <td>-</td>
96+ <td>-</td>
97+ <td>-</td>
98+ </tr>
99+ <tr>
100+ <td>dim</td>
101+ <td>输入</td>
102+ <td>表示进行去重的维度。</td>
103+ <td>-</td>
104+ <td>-</td>
105+ <td>-</td>
106+ <td>-</td>
107+ <td>-</td>
108+ </tr>
109+ <tr>
110+ <td>valueOut</td>
111+ <td>输出</td>
112+ <td>第一个输出张量,返回消除连续重复元素后的结果。</td>
113+ <td>-</td>
114+ <td>FLOAT、FLOAT16、DOUBLE、INT8、INT16、INT32、INT64、UINT8、UINT16、UINT32、UINT64、COMPLEX64、COMPLEX128、BOOL、BFLOAT16。</td>
115+ <td>-</td>
116+ <td>-</td>
117+ <td>-</td>
118+ </tr>
119+ <tr>
120+ <td>inverseOut</td>
121+ <td>输出</td>
122+ <td>第二个输出张量,当returnInverse为True时有意义,返回self中各元素在valueOut中对应元素的位置下标。</td>
123+ <td>-</td>
124+ <td>INT64</td>
125+ <td>ND</td>
126+ <td>-</td>
127+ <td>-</td>
128+ </tr>
129+ <tr>
130+ <td>countsOut</td>
131+ <td>输出</td>
132+ <td>第三个输出张量,当returnCounts为True时有意义,返回valueOut中各元素在self中连续重复出现的次数。</td>
133+ <td>-</td>
134+ <td>INT64</td>
135+ <td>ND</td>
136+ <td>-</td>
137+ <td>-</td>
138+ </tr>
139+ <tr>
140+ <td>workspaceSize</td>
141+ <td>输出</td>
142+ <td>返回需要在Device侧申请的workspace大小。</td>
143+ <td>-</td>
144+ <td>-</td>
145+ <td>-</td>
146+ <td>-</td>
147+ <td>-</td>
148+ </tr>
149+ <tr>
150+ <td>executor</td>
151+ <td>输出</td>
152+ <td>返回op执行器,包含了算子计算流程。</td>
153+ <td>-</td>
154+ <td>-</td>
155+ <td>-</td>
156+ <td>-</td>
157+ <td>-</td>
158+ </tr>
159+ </tbody></table>
160+ 
161+* **返回值**
162+ aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
163+ 第一段接口完成入参校验,出现以下场景时报错:
164+
165+ <table style="undefined;table-layout: fixed; width: 1015px"><colgroup>
166+ <col style="width: 257px">
167+ <col style="width: 101px">
168+ <col style="width: 657px">
169+ </colgroup>
170+ <thead>
171+ <tr>
172+ <th>返回值</th>
173+ <th>错误码</th>
174+ <th>描述</th>
175+ </tr></thead>
176+ <tbody>
177+ <tr>
178+ <td>ACLNN_ERR_PARAM_NULLPTR</td>
179+ <td>161001</td>
180+ <td>传入的 self 或 valueOut 或inverseOut 或 countsOut 是空指针时。</td>
181+ </tr>
182+ <tr>
183+ <td rowspan="4">ACLNN_ERR_PARAM_INVALID</td>
184+ <td rowspan="4">161002</td>
185+ <td>self 或valueOut 的数据类型不在支持的范围之内。</td>
186+ </tr>
187+ <tr>
188+ <td>self 的数据类型不在支持的范围之内。</td>
189+ </tr>
190+ <tr>
191+ <td>inverseOut 或 countsOut 的数据类型不在支持的范围之内。</td>
192+ </tr>
193+ <tr>
194+ <td>inverseOut 和 countsOut 的数据类型不一致。</td>
195+ </tr>
196+ </tbody>
197+ </table>
50 198 
51## aclnnUniqueConsecutive199## aclnnUniqueConsecutive
52 200 
53-* **参数说明**:201+* **参数说明**
54- - workspace(void\*, 入参):在Device侧申请的workspace内存地址。
55- - workspaceSize(uint64\_t, 入参):在Device侧申请的workspace大小,由第一段接口aclnnUniqueConsecutiveGetWorkspaceSize获取。
56- - executor(aclOpExecutor\*, 入参):op执行器,包含了算子计算流程。
57- - stream(aclrtStream, 入参):指定执行任务的Stream。
58 202 
59-- **返回值**:203+ <table style="undefined;table-layout: fixed; width: 950px"><colgroup>
204+ <col style="width: 122px">
205+ <col style="width: 105px">
206+ <col style="width: 723px">
207+ </colgroup>
208+ <thead>
209+ <tr>
210+ <th>参数名</th>
211+ <th>输入/输出</th>
212+ <th>描述</th>
213+ </tr></thead>
214+ <tbody>
215+ <tr>
216+ <td>workspace</td>
217+ <td>输入</td>
218+ <td>在Device侧申请的workspace内存地址。</td>
219+ </tr>
220+ <tr>
221+ <td>workspaceSize</td>
222+ <td>输入</td>
223+ <td>在Device侧申请的workspace大小,由第一段接口aclnnUniqueConsecutiveGetWorkspaceSize获取。</td>
224+ </tr>
225+ <tr>
226+ <td>executor</td>
227+ <td>输入</td>
228+ <td>op执行器,包含了算子计算流程。</td>
229+ </tr>
230+ <tr>
231+ <td>stream</td>
232+ <td>输入</td>
233+ <td>指定执行任务的Stream。</td>
234+ </tr>
235+ </tbody>
236+ </table>
237+ 
238+- **返回值**
60 239 
61 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。240 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
62 241 
@@ -63,47 +63,227 @@
63 63 
64每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用“aclnnUniqueDimGetWorkspaceSize”接口获取入参并根据计算流程计算所需workspace大小,再调用“aclnnUniqueDim”接口执行计算。64每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用“aclnnUniqueDimGetWorkspaceSize”接口获取入参并根据计算流程计算所需workspace大小,再调用“aclnnUniqueDim”接口执行计算。
65 65 
66-- `aclnnStatus aclnnUniqueDimGetWorkspaceSize(const aclTensor* self, bool sorted, bool returnInverse, int64_t dim, aclTensor* valueOut, aclTensor* inverseOut, aclTensor* countsOut, uint64_t* workspaceSize, aclOpExecutor** executor)`66+```cpp
67-- `aclnnStatus aclnnUniqueDim(void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, aclrtStream stream)`67+aclnnStatus aclnnUniqueDimGetWorkspaceSize(
68+ const aclTensor* self,
69+ bool sorted,
70+ bool returnInverse,
71+ int64_t dim,
72+ aclTensor* valueOut,
73+ aclTensor* inverseOut,
74+ aclTensor* countsOut,
75+ uint64_t* workspaceSize,
76+ aclOpExecutor** executor)
77+```
78+ 
79+```cpp
80+aclnnStatus aclnnUniqueDim(
81+ void *workspace,
82+ uint64_t workspaceSize,
83+ aclOpExecutor *executor,
84+ aclrtStream stream)
85+ ```
68 86 
69## aclnnUniqueDimGetWorkspaceSize87## aclnnUniqueDimGetWorkspaceSize
70 88 
71-- **参数说明**:89+- **参数说明**
72 90 
73- - self(aclTensor\*, 计算输入):示例中的`self`,Device侧的aclTensor。shape支持1-8维。支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND。91+ <table style="undefined;table-layout: fixed; width: 1568px"><colgroup>
74- - <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT、FLOAT16、UINT8、INT8、UINT16、INT16、UINT32、INT32、UINT64、INT64、DOUBLE、BOOL、BFLOAT16。92+ <col style="width: 126px">
75- - sorted(bool, 计算输入):表示返回的输出结果`valueOut`是否排序。93+ <col style="width: 121px">
76- - returnInverse(bool, 计算输入):表示是否返回`self`在`dim`轴上各元素在valueOut中对应元素的位置下标,True时返回,False时不返回。94+ <col style="width: 327px">
77- - dim(int64_t, 计算输入):示例中的`dim`,Host侧的整型,指定做去重操作的维度,数据类型支持INT64,取值范围为\[-self.dim(), self.dim()\)。95+ <col style="width: 283px">
78- - valueOut(aclTensor\*, 计算输出):示例中的`valueOut`,表示去重结果,Device侧的aclTensor。数据类型与`self`一致。支持[非连续的Tensor](../../../docs/zh/context/非连续的Tensor.md),[数据格式](../../../docs/zh/context/数据格式.md)支持ND。96+ <col style="width: 327px">
79- - <term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>、<term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>:数据类型支持FLOAT、FLOAT16、UINT8、INT8、UINT16、INT16、UINT32、INT32、UINT64、INT64、DOUBLE、BOOL、BFLOAT16。97+ <col style="width: 104px">
80- - inverseOut(aclTensor\*, 计算输出):示例中的`inverseOut`,表示`self`在`dim`轴上各元素在valueOut中对应元素的位置下标,Device侧的aclTensor,数据类型支持INT64。98+ <col style="width: 134px">
81- - countsOut(aclTensor\*,计算输出):示例中的`countsOut`,表示`valueOut`中的各元素在`self`中出现的次数,Device侧的aclTensor,数据类型支持INT64。99+ <col style="width: 146px">
82- - workspaceSize(uint64_t\*, 出参):返回需要在Device侧申请的workspace大小。100+ </colgroup>
83- - executor(aclOpExecutor\**, 出参):返回op执行器,包含了算子计算流程。101+ <thead>
84-- **返回值**:102+ <tr>
103+ <th>参数名</th>
104+ <th>输入/输出</th>
105+ <th>描述</th>
106+ <th>使用说明</th>
107+ <th>数据类型</th>
108+ <th>数据格式</th>
109+ <th>维度(shape)</th>
110+ <th>非连续Tensor</th>
111+ </tr></thead>
112+ <tbody>
113+ <tr>
114+ <td>self</td>
115+ <td>输入</td>
116+ <td>示例中的self。</td>
117+ <td>-</td>
118+ <td>FLOAT、FLOAT16、UINT8、INT8、UINT16、INT16、UINT32、INT32、UINT64、INT64、DOUBLE、BOOL、BFLOAT16。</td>
119+ <td>ND</td>
120+ <td>1-8</td>
121+ <td>√</td>
122+ </tr>
123+ <tr>
124+ <td>sorted</td>
125+ <td>输入</td>
126+ <td>表示返回的输出结果valueOut是否排序。</td>
127+ <td>-</td>
128+ <td>-</td>
129+ <td>-</td>
130+ <td>-</td>
131+ <td>-</td>
132+ </tr>
133+ <tr>
134+ <td>returnInverse</td>
135+ <td>输入</td>
136+ <td>表示是否返回self在dim轴上各元素在valueOut中对应元素的位置下标,True时返回,False时不返回。</td>
137+ <td>-</td>
138+ <td>-</td>
139+ <td>-</td>
140+ <td>-</td>
141+ <td>-</td>
142+ </tr>
143+ <tr>
144+ <td>dim</td>
145+ <td>输入</td>
146+ <td>示例中的dim。</td>
147+ <td>指定做去重操作的维度,数据类型支持INT64,取值范围为[-self.dim(), self.dim())。</td>
148+ <td>FLOAT、FLOAT16、UINT8、INT8、UINT16、INT16、UINT32、INT32、UINT64、INT64、DOUBLE、BOOL、BFLOAT16</td>
149+ <td>ND</td>
150+ <td></td>
151+ <td>√</td>
152+ </tr>
153+ <tr>
154+ <td>valueOut</td>
155+ <td>输出</td>
156+ <td>示例中的valueOut,表示去重结果。</td>
157+ <td>数据类型与self一致。</td>
158+ <td>-</td>
159+ <td>-</td>
160+ <td>-</td>
161+ <td>-</td>
162+ </tr>
163+ <tr>
164+ <td>inverseOut</td>
165+ <td>输出</td>
166+ <td>示例中的inverseOut,表示self在dim轴上各元素在valueOut中对应元素的位置下标。</td>
167+ <td>-</td>
168+ <td>INT64</td>
169+ <td>-</td>
170+ <td>-</td>
171+ <td>-</td>
172+ </tr>
173+ <tr>
174+ <td>countsOut</td>
175+ <td>输出</td>
176+ <td>示例中的countsOut,表示valueOut中的各元素在self中出现的次数。</td>
177+ <td>-</td>
178+ <td>INT64</td>
179+ <td>-</td>
180+ <td>-</td>
181+ <td>-</td>
182+ </tr>
183+ <tr>
184+ <td>workspaceSize</td>
185+ <td>输出</td>
186+ <td>返回需要在Device侧申请的workspace大小。</td>
187+ <td>-</td>
188+ <td>-</td>
189+ <td>-</td>
190+ <td>-</td>
191+ <td>-</td>
192+ </tr>
193+ <tr>
194+ <td>executor</td>
195+ <td>输出</td>
196+ <td>返回op执行器,包含了算子计算流程。</td>
197+ <td>-</td>
198+ <td>-</td>
199+ <td>-</td>
200+ <td>-</td>
201+ <td>-</td>
202+ </tr>
203+ </tbody></table>
204+ 
205+- **返回值**
85 206 
86 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。207 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
87- 
88- ```
89 第一段接口完成入参校验,出现以下场景时报错:208 第一段接口完成入参校验,出现以下场景时报错:
90- 返回161001(ACLNN_ERR_PARAM_NULLPTR): 1. 传入的self、valueOut、inverseOut或countsOut是空指针。209+ 
91- 返回161002(ACLNN_ERR_PARAM_INVALID): 1. self的数据类型不在支持的范围之内。210+ <table style="undefined;table-layout: fixed; width: 1035px"><colgroup>
92- 2. inverseOut和countsOut的数据类型不为INT64。211+ <col style="width: 262px">
93- 3. self和valueOut的数据类型不一致。212+ <col style="width: 103px">
94- 4. self的shape维度大于8。213+ <col style="width: 670px">
95- 5. dim值不在[-self.dim(), self.dim())范围内。214+ </colgroup>
96- ```215+ <thead>
216+ <tr>
217+ <th>返回值</th>
218+ <th>错误码</th>
219+ <th>描述</th>
220+ </tr></thead>
221+ <tbody>
222+ <tr>
223+ <td>ACLNN_ERR_PARAM_NULLPTR</td>
224+ <td>161001</td>
225+ <td>传入的self、valueOut、inverseOut或countsOut是空指针。</td>
226+ </tr>
227+ <tr>
228+ <td rowspan="5">ACLNN_ERR_PARAM_INVALID</td>
229+ <td rowspan="5">161002</td>
230+ <td>self的数据类型不在支持的范围之内。</td>
231+ </tr>
232+ <tr>
233+ <td>inverseOut和countsOut的数据类型不为INT64。</td>
234+ </tr>
235+ <tr>
236+ <td>self和valueOut的数据类型不一致。</td>
237+ </tr>
238+ <tr>
239+ <td>self的shape维度大于8。</td>
240+ </tr>
241+ <tr>
242+ <td>dim值不在[-self.dim(), self.dim())范围内。</td>
243+ </tr>
244+ </tbody>
245+ </table>
97 246 
98## aclnnUniqueDim247## aclnnUniqueDim
99 248 
100-- **参数说明**:249+- **参数说明**
101 250 
102- - workspace(void\*, 入参):在Device侧申请的workspace内存地址。251+ <table style="undefined;table-layout: fixed; width: 950px"><colgroup>
103- - workspaceSize(uint64_t, 入参):在Device侧申请的workspace大小,由第一段接口aclnnUniqueDimGetWorkspaceSize获取。252+ <col style="width: 122px">
104- - executor(aclOpExecutor\*, 入参):op执行器,包含了算子计算流程。253+ <col style="width: 105px">
105- - stream(aclrtStream, 入参):指定执行任务的Stream。254+ <col style="width: 723px">
106-- **返回值**:255+ </colgroup>
256+ <thead>
257+ <tr>
258+ <th>参数名</th>
259+ <th>输入/输出</th>
260+ <th>描述</th>
261+ </tr></thead>
262+ <tbody>
263+ <tr>
264+ <td>workspace</td>
265+ <td>输入</td>
266+ <td>在Device侧申请的workspace内存地址。</td>
267+ </tr>
268+ <tr>
269+ <td>workspaceSize</td>
270+ <td>输入</td>
271+ <td>在Device侧申请的workspace大小,由第一段接口aclnnUniqueDimGetWorkspaceSize获取。</td>
272+ </tr>
273+ <tr>
274+ <td>executor</td>
275+ <td>输入</td>
276+ <td>op执行器,包含了算子计算流程。</td>
277+ </tr>
278+ <tr>
279+ <td>stream</td>
280+ <td>输入</td>
281+ <td>指定执行任务的Stream。</td>
282+ </tr>
283+ </tbody>
284+ </table>
285+ 
286+- **返回值**
107 287 
108 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。288 aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
109 289