已合并
nn仓商分资料整改 #3875
sunchun创建于 4月16日
nn仓商分资料整改 #3875
已合并
从已删除 :nntext0416分支合入到cann/ops-nn9.0.0
共 5 个文件变更+638-777
| @@ -1,20 +1,24 @@ | |||
| 1 | # aclnnScatterAdd | 1 | # 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 == 0 | 24 | 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 | ## aclnnScatterAddGetWorkspaceSize | 87 | ## 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 | ## aclnnScatterAdd | 221 | ## 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 | ## aclnnUniqueConsecutiveGetWorkspaceSize | 43 | ## 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 | ## aclnnUniqueConsecutive | 199 | ## 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 | ## aclnnUniqueDimGetWorkspaceSize | 87 | ## 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 | ## aclnnUniqueDim | 247 | ## 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 | ||