已合并
docs: 为aclnnPrecisionCompare、aclnnProd、aclnnProdDim添加计算公式,新增aclnnBitwiseAndTensorOut、aclnnInplaceBitwiseAndTensorOut文档 #1834
docs: 为aclnnPrecisionCompare、aclnnProd、aclnnProdDim添加计算公式,新增aclnnBitwiseAndTensorOut、aclnnInplaceBitwiseAndTensorOut文档 #1834
已合并
zhangqijia1创建于 3月23日
5 个文件变更+549-3
Mdocs/zh/op_api_list.md+1-0
@@ -53,6 +53,7 @@ ${INSTALL_DIR}表示CANN安装后文件路径;\$\{ops\_project\}表示算子
53| [aclnnBitwiseNot](../../math/bitwise_not/docs/aclnnBitwiseNot.md) | 输入为BOOL型tensor时,进行逻辑非运算;输入为INT型时进行按位非运算。 | 默认确定性实现|53| [aclnnBitwiseNot](../../math/bitwise_not/docs/aclnnBitwiseNot.md) | 输入为BOOL型tensor时,进行逻辑非运算;输入为INT型时进行按位非运算。 | 默认确定性实现|
54| [aclnnBitwiseAndScalar](../../math/bitwise_and/docs/aclnnBitwiseAndScalar.md) | 计算输入tensor中每个元素和输入标量的按位与结果。 | 默认确定性实现|54| [aclnnBitwiseAndScalar](../../math/bitwise_and/docs/aclnnBitwiseAndScalar.md) | 计算输入tensor中每个元素和输入标量的按位与结果。 | 默认确定性实现|
55| [aclnnBitwiseAndTensor](../../math/bitwise_and/docs/aclnnBitwiseAndTensor.md) | 输入为BOOL型tensor时,进行逻辑与运算;输入为INT型时,进行位与运算。 | 默认确定性实现|55| [aclnnBitwiseAndTensor](../../math/bitwise_and/docs/aclnnBitwiseAndTensor.md) | 输入为BOOL型tensor时,进行逻辑与运算;输入为INT型时,进行位与运算。 | 默认确定性实现|
56+| [aclnnBitwiseAndTensorOut&aclnnInplaceBitwiseAndTensorOut](../../math/bitwise_and/docs/aclnnBitwiseAndTensorOut&aclnnInplaceBitwiseAndTensorOut.md) | 输入为BOOL型tensor时,进行逻辑与运算;输入为INT型时,进行位与运算。 | 默认确定性实现|
56| [aclnnBitwiseOrScalar&aclnnInplaceBitwiseOrScalar](../../math/bitwise_or/docs/aclnnBitwiseOrScalar&aclnnInplaceBitwiseOrScalar.md) | 计算输入张量self中每个元素和输入标量other的按位或。 | 默认确定性实现|57| [aclnnBitwiseOrScalar&aclnnInplaceBitwiseOrScalar](../../math/bitwise_or/docs/aclnnBitwiseOrScalar&aclnnInplaceBitwiseOrScalar.md) | 计算输入张量self中每个元素和输入标量other的按位或。 | 默认确定性实现|
57| [aclnnBitwiseOrTensor&aclnnInplaceBitwiseOrTensor](../../math/bitwise_or/docs/aclnnBitwiseOrTensor&aclnnInplaceBitwiseOrTensor.md) | 计算张量self中每个元素与other张量中对应位置的元素的按位或。 | 默认确定性实现|58| [aclnnBitwiseOrTensor&aclnnInplaceBitwiseOrTensor](../../math/bitwise_or/docs/aclnnBitwiseOrTensor&aclnnInplaceBitwiseOrTensor.md) | 计算张量self中每个元素与other张量中对应位置的元素的按位或。 | 默认确定性实现|
58| [aclnnBitwiseXorScalar&aclnnInplaceBitwiseXorScalar](../../math/bitwise_xor/docs/aclnnBitwiseXorScalar&aclnnInplaceBitwiseXorScalar.md) | 计算输入张量self中每个元素和输入标量other的按位异或,输入self和other必须是整数或布尔类型,对于布尔类型,计算逻辑异或。 | 默认确定性实现|59| [aclnnBitwiseXorScalar&aclnnInplaceBitwiseXorScalar](../../math/bitwise_xor/docs/aclnnBitwiseXorScalar&aclnnInplaceBitwiseXorScalar.md) | 计算输入张量self中每个元素和输入标量other的按位异或,输入self和other必须是整数或布尔类型,对于布尔类型,计算逻辑异或。 | 默认确定性实现|
Amath/bitwise_and/docs/aclnnBitwiseAndTensorOut&aclnnInplaceBitwiseAndTensorOut.md+521-0
@@ -0,0 +1,521 @@
1+# aclnnBitwiseAndTensorOut&aclnnInplaceBitwiseAndTensorOut
S
Ssunday4月3日

问题: 与同目录其他 aclnn 文档相比,标题下缺少「查看源码」链接,版式不统一。

建议: 在标题行下增加一行:[📄 查看源码](https://gitcode.com/cann/ops-math/tree/master/math/bitwise_and)(与同系列文档一致)。

likedislike
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+- 接口功能:输入为BOOL型tensor时,进行逻辑与运算;输入为INT型时,进行位与运算。
17+ 
18+- 计算公式:
19+ 
20+ $$
21+ out_i = self_i \& other_i
22+ $$
23+ 
24+## 函数原型
25+ 
26+- aclnnBitwiseAndTensorOut和aclnnInplaceBitwiseAndTensorOut实现相同的功能,使用区别如下,请根据自身实际场景选择合适的算子。
27+ - aclnnBitwiseAndTensorOut:需新建一个输出张量对象存储计算结果。
28+ - aclnnInplaceBitwiseAndTensorOut:无需新建输出张量对象,直接在输入张量的内存中存储计算结果。
29+- 每个算子分为[两段式接口](../../../docs/zh/context/两段式接口.md),必须先调用"aclnnBitwiseAndTensorOutGetWorkspaceSize"接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用"aclnnBitwiseAndTensorOut"接口执行计算。
S
Ssunday4月3日

问题: 「两段式接口」说明与「函数原型」仅覆盖了 aclnnBitwiseAndTensorOut 的 GetWorkspaceSize + 执行接口,未说明也可使用 aclnnInplaceBitwiseAndTensorOutGetWorkspaceSizeaclnnInplaceBitwiseAndTensorOut;且未给出 Inplace 的两个 C++ 原型块。

建议: 参照同仓库 aclnnBitwiseOrTensor&aclnnInplaceBitwiseOrTensor.md:在说明中用「或者」并列 Inplace 两段式流程,并在 函数原型 一节补充 Inplace 的 GetWorkspaceSize 与第二段接口的代码块,与 aclnn_bitwiseand.h 保持一致。

likedislike
30+ 
31+```Cpp
32+aclnnStatus aclnnBitwiseAndTensorOutGetWorkspaceSize(
33+ const aclTensor* self,
34+ const aclTensor* other,
35+ aclTensor* out,
36+ uint64_t* workspaceSize,
37+ aclOpExecutor** executor)
38+```
39+ 
40+```Cpp
41+aclnnStatus aclnnBitwiseAndTensorOut(
42+ void* workspace,
43+ uint64_t workspaceSize,
44+ aclOpExecutor* executor,
45+ const aclrtStream stream)
S
Ssunday4月3日

问题: 文档中第二段接口参数写为 const aclrtStream stream,与公开头文件 aclnn_bitwiseand.h 中的签名 aclrtStream stream 不一致。

建议: 与头文件 API 签名对齐(去掉 const 或按实际发布版本为准)。

likedislike
46+```
47+ 
48+## aclnnBitwiseAndTensorOutGetWorkspaceSize
49+ 
50+- **参数说明:**
51+ 
52+ <table style="undefined;table-layout: fixed; width: 1523px"><colgroup>
53+ <col style="width: 146px">
54+ <col style="width: 120px">
55+ <col style="width: 301px">
56+ <col style="width: 219px">
57+ <col style="width: 328px">
58+ <col style="width: 120px">
59+ <col style="width: 143px">
60+ <col style="width: 146px">
61+ </colgroup>
62+ <thead>
63+ <tr>
64+ <th>参数名</th>
65+ <th>输入/输出</th>
66+ <th>描述</th>
67+ <th>使用说明</th>
68+ <th>数据类型</th>
69+ <th>数据格式</th>
70+ <th>维度(shape)</th>
71+ <th>非连续Tensor</th>
72+ </tr></thead>
73+ <tbody>
74+ <tr>
75+ <td>self(aclTensor*)</td>
76+ <td>输入</td>
77+ <td>输入tensor,公式中的self。</td>
78+ <td>数据类型需要与other的数据类型满足<a href="../../../docs/zh/context/互推导关系.md" target="_blank">数据类型推导规则</a>。<br>shape需要与other满足<a href="../../../docs/zh/context/broadcast关系.md" target="_blank">broadcast关系</a>。</td>
79+ <td>INT16、UINT16、INT32、INT64、INT8、UINT8、BOOL</td>
80+ <td>ND</td>
81+ <td>0-8</td>
82+ <td>√</td>
83+ </tr>
84+ <tr>
85+ <td>other(aclTensor*)</td>
86+ <td>输入</td>
87+ <td>输入tensor,公式中的other。</td>
88+ <td>数据类型需要与self的数据类型满足<a href="../../../docs/zh/context/互推导关系.md" target="_blank">数据类型推导规则</a>。<br>shape需要与self满足<a href="../../../docs/zh/context/broadcast关系.md" target="_blank">broadcast关系</a>。</td>
89+ <td>INT16、UINT16、INT32、INT64、INT8、UINT8、BOOL</td>
90+ <td>ND</td>
91+ <td>0-8</td>
92+ <td>√</td>
93+ </tr>
94+ <tr>
95+ <td>out(aclTensor*)</td>
96+ <td>输出</td>
97+ <td>输出tensor,公式中的out。</td>
98+ <td>数据类型需要是self与other推导之后可转换的数据类型。<br>shape需要是self与other满足<a href="../../../docs/zh/context/broadcast关系.md" target="_blank">broadcast关系</a>之后的shape。</td>
99+ <td>BOOL、INT8、INT16、INT32、INT64、UINT8、UINT16、UINT32、UINT64</td>
100+ <td>ND</td>
101+ <td>0-8</td>
102+ <td>√</td>
103+ </tr>
104+ <tr>
105+ <td>workspaceSize(uint64_t*)</td>
106+ <td>输出</td>
107+ <td>返回需要在Device侧申请的workspace大小。</td>
108+ <td>-</td>
109+ <td>-</td>
110+ <td>-</td>
111+ <td>-</td>
112+ <td>-</td>
113+ </tr>
114+ <tr>
115+ <td>executor(aclOpExecutor**)</td>
116+ <td>输出</td>
117+ <td>返回op执行器,包含了算子计算流程。</td>
118+ <td>-</td>
119+ <td>-</td>
120+ <td>-</td>
121+ <td>-</td>
122+ <td>-</td>
123+ </tr>
124+ </tbody></table>
125+ 
126+ 
127+- **返回值:**
128+ 
129+ aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
130+ 
131+ 第一段接口完成入参校验,出现以下场景时报错:
132+ 
133+ <table style="undefined;table-layout: fixed; width: 1150px"><colgroup>
134+ <col style="width: 300px">
135+ <col style="width: 134px">
136+ <col style="width: 716px">
137+ </colgroup>
138+ <thead>
139+ <tr>
140+ <th>返回码</th>
141+ <th>错误码</th>
142+ <th>描述</th>
143+ </tr></thead>
144+ <tbody>
145+ <tr>
146+ <td>ACLNN_ERR_PARAM_NULLPTR</td>
147+ <td>161001</td>
148+ <td>传入的self、other或out是空指针。</td>
149+ </tr>
150+ <tr>
151+ <td rowspan="5">ACLNN_ERR_PARAM_INVALID</td>
152+ <td rowspan="5">161002</td>
153+ <td>self和other的数据类型不在支持的范围之内。</td>
154+ </tr>
155+ <tr>
156+ <td>self和other不满足数据类型推导规则。</td>
157+ </tr>
158+ <tr>
159+ <td>self和other推导出的数据类型无法转换为指定输出out的类型。</td>
160+ </tr>
161+ <tr>
162+ <td>self和other的shape无法做broadcast。</td>
163+ </tr>
164+ <tr>
165+ <td>self、other、out的维度超过8维。</td>
166+ </tr>
167+ </tbody></table>
168+ 
169+## aclnnBitwiseAndTensorOut
170+ 
171+- **参数说明:**
172+ 
173+ <table style="undefined;table-layout: fixed; width: 953px"><colgroup>
174+ <col style="width: 173px">
175+ <col style="width: 112px">
176+ <col style="width: 668px">
177+ </colgroup>
178+ <thead>
179+ <tr>
180+ <th>参数名</th>
181+ <th>输入/输出</th>
182+ <th>描述</th>
183+ </tr></thead>
184+ <tbody>
185+ <tr>
186+ <td>workspace</td>
187+ <td>输入</td>
188+ <td>在Device侧申请的workspace内存地址。</td>
189+ </tr>
190+ <tr>
191+ <td>workspaceSize</td>
192+ <td>输入</td>
193+ <td>在Device侧申请的workspace大小,由第一段接口aclnnBitwiseAndTensorOutGetWorkspaceSize获取。</td>
194+ </tr>
195+ <tr>
196+ <td>executor</td>
197+ <td>输入</td>
198+ <td>op执行器,包含了算子计算流程。</td>
199+ </tr>
200+ <tr>
201+ <td>stream</td>
202+ <td>输入</td>
203+ <td>指定执行任务的Stream。</td>
204+ </tr>
205+ </tbody>
206+ </table>
207+ 
208+ 
209+- **返回值:**
210+ 
211+ aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
212+ 
213+## aclnnInplaceBitwiseAndTensorOutGetWorkspaceSize
214+ 
215+- **参数说明:**
216+ 
217+ <table style="undefined;table-layout: fixed; width: 1523px"><colgroup>
218+ <col style="width: 146px">
219+ <col style="width: 120px">
220+ <col style="width: 301px">
221+ <col style="width: 219px">
222+ <col style="width: 328px">
223+ <col style="width: 120px">
224+ <col style="width: 143px">
225+ <col style="width: 146px">
226+ </colgroup>
227+ <thead>
228+ <tr>
229+ <th>参数名</th>
230+ <th>输入/输出</th>
231+ <th>描述</th>
232+ <th>使用说明</th>
233+ <th>数据类型</th>
234+ <th>数据格式</th>
235+ <th>维度(shape)</th>
236+ <th>非连续Tensor</th>
237+ </tr></thead>
238+ <tbody>
239+ <tr>
240+ <td>selfRef(aclTensor*)</td>
241+ <td>输入/输出</td>
242+ <td>输入和输出tensor,公式中的selfRef。</td>
243+ <td>数据类型需要与other的数据类型满足<a href="../../../docs/zh/context/互推导关系.md" target="_blank">数据类型推导规则</a>。<br>shape需要与other满足<a href="../../../docs/zh/context/broadcast关系.md" target="_blank">broadcast关系</a>。</td>
244+ <td>INT16、UINT16、INT32、INT64、INT8、UINT8、BOOL</td>
245+ <td>ND</td>
246+ <td>0-8</td>
247+ <td>√</td>
248+ </tr>
249+ <tr>
250+ <td>other(aclTensor*)</td>
251+ <td>输入</td>
252+ <td>输入tensor,公式中的other。</td>
253+ <td>数据类型需要与selfRef的数据类型满足<a href="../../../docs/zh/context/互推导关系.md" target="_blank">数据类型推导规则</a>。<br>shape需要与selfRef满足<a href="../../../docs/zh/context/broadcast关系.md" target="_blank">broadcast关系</a>。</td>
254+ <td>INT16、UINT16、INT32、INT64、INT8、UINT8、BOOL</td>
255+ <td>ND</td>
256+ <td>0-8</td>
257+ <td>√</td>
258+ </tr>
259+ <tr>
260+ <td>workspaceSize(uint64_t*)</td>
261+ <td>输出</td>
262+ <td>返回需要在Device侧申请的workspace大小。</td>
263+ <td>-</td>
264+ <td>-</td>
265+ <td>-</td>
266+ <td>-</td>
267+ <td>-</td>
268+ </tr>
269+ <tr>
270+ <td>executor(aclOpExecutor**)</td>
271+ <td>输出</td>
272+ <td>返回op执行器,包含了算子计算流程。</td>
273+ <td>-</td>
274+ <td>-</td>
275+ <td>-</td>
276+ <td>-</td>
277+ <td>-</td>
278+ </tr>
279+ </tbody></table>
280+ 
281+ 
282+- **返回值:**
283+ 
284+ aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
285+ 
286+ 第一段接口完成入参校验,出现以下场景时报错:
287+ 
288+ <table style="undefined;table-layout: fixed; width: 1150px"><colgroup>
289+ <col style="width: 300px">
290+ <col style="width: 134px">
291+ <col style="width: 716px">
292+ </colgroup>
293+ <thead>
294+ <tr>
295+ <th>返回码</th>
296+ <th>错误码</th>
297+ <th>描述</th>
298+ </tr></thead>
299+ <tbody>
300+ <tr>
301+ <td>ACLNN_ERR_PARAM_NULLPTR</td>
302+ <td>161001</td>
303+ <td>传入的selfRef或other是空指针。</td>
304+ </tr>
305+ <tr>
306+ <td rowspan="5">ACLNN_ERR_PARAM_INVALID</td>
307+ <td rowspan="5">161002</td>
308+ <td>selfRef和other的数据类型不在支持的范围之内。</td>
309+ </tr>
310+ <tr>
311+ <td>selfRef和other不满足数据类型推导规则。</td>
312+ </tr>
313+ <tr>
314+ <td>selfRef和other推导出的数据类型无法转换为指定输出selfRef的类型。</td>
315+ </tr>
316+ <tr>
317+ <td>selfRef和other的shape无法做broadcast。</td>
318+ </tr>
319+ <tr>
320+ <td>selfRef、other的维度超过8维。</td>
321+ </tr>
322+ </tbody></table>
323+ 
324+## aclnnInplaceBitwiseAndTensorOut
325+ 
326+- **参数说明:**
327+ 
328+ <table style="undefined;table-layout: fixed; width: 1151px"><colgroup>
329+ <col style="width: 184px">
330+ <col style="width: 134px">
331+ <col style="width: 833px">
332+ </colgroup>
333+ <thead>
334+ <tr>
335+ <th>参数名</th>
336+ <th>输入/输出</th>
337+ <th>描述</th>
338+ </tr></thead>
339+ <tbody>
340+ <tr>
341+ <td>workspace</td>
342+ <td>输入</td>
343+ <td>在Device侧申请的workspace内存地址。</td>
344+ </tr>
345+ <tr>
346+ <td>workspaceSize</td>
347+ <td>输入</td>
348+ <td>在Device侧申请的workspace大小,由第一段接口aclnnInplaceBitwiseAndTensorOutGetWorkspaceSize获取。</td>
349+ </tr>
350+ <tr>
351+ <td>executor</td>
352+ <td>输入</td>
353+ <td>op执行器,包含了算子计算流程。</td>
354+ </tr>
355+ <tr>
356+ <td>stream</td>
357+ <td>输入</td>
358+ <td>指定执行任务的Stream。</td>
359+ </tr>
360+ </tbody>
361+ </table>
362+ 
363+ 
364+- **返回值:**
365+ 
366+ aclnnStatus:返回状态码,具体参见[aclnn返回码](../../../docs/zh/context/aclnn返回码.md)。
367+ 
368+## 约束说明
369+ 
370+- 确定性计算:
371+ - aclnnBitwiseAndTensorOut默认确定性实现。
372+ - aclnnInplaceBitwiseAndTensorOut默认确定性实现。
373+ 
374+## 调用示例
375+ 
376+示例代码如下,仅供参考,具体编译和执行过程请参考[编译与运行样例](../../../docs/zh/context/编译与运行样例.md)。
377+ 
378+```Cpp
379+#include <iostream>
380+#include <vector>
381+#include "acl/acl.h"
382+#include "aclnnop/aclnn_bitwise_and_tensor.h"
S
Ssunday4月3日

问题: 调用示例中的头文件与 aclnnBitwiseAndTensorOut / aclnnInplaceBitwiseAndTensorOut 的实际声明位置不一致。

建议: aclnn_bitwise_and_tensor.h 仅包含 aclnnBitwiseAndTensor 等接口;TensorOut 系列声明在 aclnn_bitwiseand.h(与仓库内 test_aclnn_bitwise_and.cpp 一致)。请将示例中的 #include 改为与对外发布一致的 aclnnop/aclnn_bitwiseand.h(若安装路径不同,以 CANN 发布头文件为准,但需与声明所在头一致)。

likedislike
383+ 
384+#define CHECK_RET(cond, return_expr) \
385+ do { \
386+ if (!(cond)) { \
387+ return_expr; \
388+ } \
389+ } while (0)
390+ 
391+#define LOG_PRINT(message, ...) \
392+ do { \
393+ printf(message, ##__VA_ARGS__); \
394+ } while (0)
395+ 
396+int64_t GetShapeSize(const std::vector<int64_t>& shape) {
397+ int64_t shape_size = 1;
398+ for (auto i : shape) {
399+ shape_size *= i;
400+ }
401+ return shape_size;
402+}
403+ 
404+int Init(int32_t deviceId, aclrtStream* stream) {
405+ // 固定写法,资源初始化
406+ auto ret = aclInit(nullptr);
407+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);
408+ ret = aclrtSetDevice(deviceId);
409+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);
410+ ret = aclrtCreateStream(stream);
411+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);
412+ 
413+ return 0;
414+}
415+ 
416+template <typename T>
417+int CreateAclTensor(const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr,
418+ aclDataType dataType, aclTensor** tensor) {
419+ auto size = GetShapeSize(shape) * sizeof(T);
420+ // 调用aclrtMalloc申请device侧内存
421+ auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);
422+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);
423+ 
424+ // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上
425+ ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);
426+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);
427+ 
428+ // 计算连续tensor的strides
429+ std::vector<int64_t> strides(shape.size(), 1);
430+ for (int64_t i = shape.size() - 2; i >= 0; i--) {
431+ strides[i] = shape[i + 1] * strides[i + 1];
432+ }
433+ 
434+ // 调用aclCreateTensor接口创建aclTensor
435+ *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND,
436+ shape.data(), shape.size(), *deviceAddr);
437+ return 0;
438+}
439+ 
440+int main() {
441+ // 1. (固定写法)device/stream初始化, 参考acl对外接口列表
442+ // 根据自己的实际device填写deviceId
443+ int32_t deviceId = 0;
444+ aclrtStream stream;
445+ auto ret = Init(deviceId, &stream);
446+ // check根据自己的需要处理
447+ CHECK_RET(ret == 0, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);
448+ 
449+ // 2. 构造输入与输出,需要根据API的接口自定义构造
450+ std::vector<int64_t> selfShape = {4, 2};
451+ std::vector<int64_t> otherShape = {4, 2};
452+ std::vector<int64_t> outShape = {4, 2};
453+ void* selfDeviceAddr = nullptr;
454+ void* otherDeviceAddr = nullptr;
455+ void* outDeviceAddr = nullptr;
456+ aclTensor* self = nullptr;
457+ aclTensor* other = nullptr;
458+ aclTensor* out = nullptr;
459+ std::vector<int64_t> selfHostData = {0, 1, 2, 3, 4, 5, 6, 7};
460+ std::vector<int64_t> otherHostData = {1, 1, 2, 3, 3, 3, 4, 4};
461+ std::vector<int64_t> outHostData = {0, 0, 0, 0, 0, 0, 0, 0};
462+ 
463+ // 创建self aclTensor
464+ ret = CreateAclTensor(selfHostData, selfShape, &selfDeviceAddr, aclDataType::ACL_INT64, &self);
465+ CHECK_RET(ret == ACL_SUCCESS, return ret);
466+ // 创建other aclTensor
467+ ret = CreateAclTensor(otherHostData, otherShape, &otherDeviceAddr, aclDataType::ACL_INT64, &other);
468+ CHECK_RET(ret == ACL_SUCCESS, return ret);
469+ // 创建out aclTensor
470+ ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_INT64, &out);
471+ CHECK_RET(ret == ACL_SUCCESS, return ret);
472+ 
473+ // 3. 调用CANN算子库API,需要修改为具体的API
474+ uint64_t workspaceSize = 0;
475+ aclOpExecutor* executor;
476+ // 调用aclnnBitwiseAndTensorOut第一段接口
477+ ret = aclnnBitwiseAndTensorOutGetWorkspaceSize(self, other, out, &workspaceSize, &executor);
478+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnBitwiseAndTensorOutGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);
479+ // 根据第一段接口计算出的workspaceSize申请device内存
480+ void* workspaceAddr = nullptr;
481+ if (workspaceSize > 0) {
482+ ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
483+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret;);
484+ }
485+ // 调用aclnnBitwiseAndTensorOut第二段接口
486+ ret = aclnnBitwiseAndTensorOut(workspaceAddr, workspaceSize, executor, stream);
487+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnBitwiseAndTensorOut failed. ERROR: %d\n", ret); return ret);
488+ 
489+ // 4. (固定写法)同步等待任务执行结束
490+ ret = aclrtSynchronizeStream(stream);
491+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
492+ 
493+ // 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改
494+ auto size = GetShapeSize(outShape);
495+ std::vector<int64_t> resultData(size, 0);
496+ ret = aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr, size * sizeof(int64_t),
497+ ACL_MEMCPY_DEVICE_TO_HOST);
498+ CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
499+ for (int64_t i = 0; i < size; i++) {
500+ LOG_PRINT("result[%ld] is: %ld\n", i, resultData[i]);
501+ }
502+ 
503+ // 6. 释放aclTensor
504+ aclDestroyTensor(self);
505+ aclDestroyTensor(other);
506+ aclDestroyTensor(out);
507+ 
508+ // 7. 释放device资源
509+ aclrtFree(selfDeviceAddr);
510+ aclrtFree(otherDeviceAddr);
511+ aclrtFree(outDeviceAddr);
512+ if (workspaceSize > 0) {
513+ aclrtFree(workspaceAddr);
514+ }
515+ aclrtDestroyStream(stream);
516+ aclrtResetDevice(deviceId);
517+ aclFinalize();
518+ 
519+ return 0;
520+}
521+```
Mmath/precision_compare/docs/aclnnPrecisionCompare.md+9-1
@@ -15,7 +15,15 @@
15 15 
16## 功能说明16## 功能说明
17 17 
18-计算两个Tensor元素是否相同,进行精度比对,返回算子执行的状态码,不会触发管理面故障上报。18+- 接口功能:计算两个Tensor元素是否相同,进行精度比对,返回算子执行的状态码,不会触发管理面故障上报。
19+ 
20+- 计算公式:
21+ 
22+ $$
23+ golden_i = realdata_i, \quad i = 0, 1, \ldots, n-1
24+ $$
25+ 
26+ 逐元素比对golden与realdata是否相同,out返回比对结果状态码(0表示通过,非零表示异常)。
19 27 
20## 函数原型28## 函数原型
21 29 
Mmath/reduce_prod/docs/aclnnProd.md+9-1
@@ -16,7 +16,15 @@
16 16 
17## 功能说明17## 功能说明
18 18 
19-返回输入tensor中所有元素的乘积。19+- 接口功能:返回输入tensor中所有元素的乘积。
20+ 
21+- 计算公式:
22+ 
23+ $$
24+ out = \prod_{i=0}^{n-1} self_i
25+ $$
26+ 
27+ 其中$n$为self中元素的总数,$self_i$为self中第$i$个元素。
20 28 
21## 函数原型29## 函数原型
22 30 
Mmath/reduce_prod/docs/aclnnProdDim.md+9-1
@@ -16,7 +16,15 @@
16 16 
17## 功能说明17## 功能说明
18 18 
19-返回输入tensor给定维度上每行的乘积。19+- 接口功能:返回输入tensor给定维度上每行的乘积。
20+ 
21+- 计算公式:
22+ 
23+ $$
24+ out = \prod_{i=0}^{S_{dim}-1} self_{[..., \, i, \, ...]}
25+ $$
26+ 
27+ 其中$S_{dim}$为self在维度$dim$上的大小,$dim$为指定的缩减维度,$keepDim$控制输出是否保留该维度。
20 28 
21## 函数原型29## 函数原型
22 30