资讯动态

aclnnReal 算子新手指南:快速掌握复数取实部算子的完整调用流程

发布时间:2026/10/20 23:49:36 来源:尧图企业网站定制
aclnnReal 算子新手指南快速掌握复数取实部算子的完整调用流程【免费下载链接】ops-math本项目是CANN提供的数学类基础计算算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-math在 ops-math 算子库中aclnnReal 用于为输入张量的每一个元素取实数部分是处理复数数据的基础算子。如果你需要在 NPU 上剥离复数张量的虚部、只保留实部或者对实数张量做直接透传它就是你要找的接口。下面这篇指南带你从零跑通它的完整调用流程。算子定位与数学原理它到底在算什么一句话概括aclnnReal 对输入张量的每个元素 $input_i$ 取复数实部 $a_i$输入是复数时丢掉虚部输入本身是实数时原样输出。它的计算公式非常直接$$ input_i a_i b_i * ja_i是复数的实部b_i是复数的虚部 $$$$ output_i a_i $$所以复数 COMPLEX64 进、FLOAT 出实数 FLOAT 进、FLOAT 出行为完全一致地按公式执行不存在任何分支逻辑这也是它结果确定性的来源。两段式调用workspace 和 executor 分别是什么CANN 的单算子 API 都采用两段式调用第一段aclnnRealGetWorkspaceSize负责准备第二段aclnnReal负责执行。理解两个核心概念就能串起来workspace它是什么——除输入/输出之外算子在 NPU 上完成计算所需的临时内存。怎么用——第一段接口会把本次计算需要的 workspaceSize 算出来告诉你你按这个大小调用aclrtMalloc申请 Device 侧内存再把它交给第二段接口。executoraclOpExecutor它是什么——包含整个算子计算流程的执行器对象可以理解成打包好的执行计划。怎么用——由第一段接口创建并返回第二段接口拿着它在指定 stream 上真正发起计算。⚠️ 一个新手最容易踩的坑executor 是一次性的第二段接口不能对同一个 executor 重复调用重复调用会出现异常。需要重算就重新走一遍第一段接口。参数速查一次看全两段接口的全部参数把两段接口的参数合在一张表里方便对照参数名所属接口输入/输出描述数据类型selfaclnnRealGetWorkspaceSize输入需要取实部的输入张量数据格式 ND支持非连续 TensorFLOAT、FLOAT16、COMPLEX64、COMPLEX32、COMPLEX128outaclnnRealGetWorkspaceSize输出实部输出张量数据格式 ND支持非连续 TensorFLOAT、FLOAT16、DOUBLEworkspaceSizeaclnnRealGetWorkspaceSize输出返回需要在 Device 侧申请的 workspace 大小uint64_texecutoraclnnRealGetWorkspaceSize输出返回 op 执行器包含算子计算流程aclOpExecutor**workspaceaclnnReal输入Device 侧申请的 workspace 内存地址void*workspaceSizeaclnnReal输入Device 侧申请的 workspace 大小由第一段接口获取uint64_texecutoraclnnReal输入op 执行器包含算子计算流程aclOpExecutor*streamaclnnReal输入指定执行任务的 StreamaclrtStream两段接口的函数原型如下建议收藏备用// 第一段入参校验 计算 workspace 大小 创建执行器 aclnnStatus aclnnRealGetWorkspaceSize( const aclTensor* self, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor); // 第二段在指定 stream 上执行计算 aclnnStatus aclnnReal( void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream);输入输出数据类型配对进什么类型出什么类型类型配对规则很简单复数进来按分量精度换成对应的实数类型实数进来原类型透传。self 类型out 类型FLOATFLOATFLOAT16FLOAT16COMPLEX64FLOATCOMPLEX32FLOAT16COMPLEX128DOUBLE如果碰到ACLNN_ERR_PARAM_INVALID报错九成是这里的类型配对没对上先核对自己传的 self 和 out 数据类型是否在这个表里。aclnnReal 错误码速查报错了先看这里第一段接口会完成入参校验遇到下面两类情况会直接返回错误码不需要等到第二段错误码名称错误编号触发原因ACLNN_ERR_PARAM_NULLPTR161001传入的 tensor 或 out 是空指针ACLNN_ERR_PARAM_INVALID161002self 的数据类型和数据格式不在支持的范围之内工程上的建议每一步调用初始化、拷数据、两段接口、同步都检查aclnnStatus返回码出错时尽早把状态码打印出来定位比盯着现象猜要快得多。完整的返回码定义可以查阅 aclnn返回码。使用约束调用前必须满足的条件跑通之前先对照下面几条自查你的输入self 与 out 的 shape 必须相同输出就是逐元素的实部不改变维度。支持动态 shape 和动态 rank不需要提前把维度全部写死。输入数据不能为空。确定性计算aclnnReal 默认确定性实现同样的输入每次运行都得到同样的结果。产品支持Atlas A2 训练系列产品 / Atlas A2 推理系列产品。最小调用示例60 行内跑通 aclnnReal下面是精简后的最小可运行骨架按初始化 → 建 tensor → 第一段 → 申请 workspace → 第二段 → 同步 → 释放的顺序走完整工程版可以见 编译与运行样例。#include aclnnop/aclnn_real.h #include acl/acl.h #include vector int main() { // 1. 资源初始化固定写法根据自己的 device 填写 deviceId int32_t deviceId 0; aclrtStream stream; auto ret aclInit(nullptr); ret aclrtSetDevice(deviceId); ret aclrtCreateStream(stream); if (ret ! ACL_SUCCESS) { return ret; // 初始化失败直接返回先查环境 } // 2. 构造输入/输出shape 必须一致这里用 4x2 的 FLOAT 复数实部示例 std::vectorint64_t shape {4, 2}; void* selfAddr nullptr; void* outAddr nullptr; ret aclrtMalloc(selfAddr, shape[0] * shape[1] * sizeof(float), ACL_MEM_MALLOC_HUGE_FIRST); ret aclrtMalloc(outAddr, shape[0] * shape[1] * sizeof(float), ACL_MEM_MALLOC_HUGE_FIRST); // 将 host 数据经 aclrtMemcpy 拷入 selfAddr再调用 aclCreateTensor 创建 self / out aclTensor* self nullptr; // 由 aclCreateTensor 创建 aclTensor* out nullptr; // 3. 第一段接口校验 计算 workspace 大小 创建执行器 uint64_t workspaceSize 0; aclOpExecutor* executor nullptr; ret aclnnRealGetWorkspaceSize(self, out, workspaceSize, executor); if (ret ! ACL_SUCCESS) { return ret; // 常见于 161001/161002见错误码速查 } // 4. 按第一段接口返回的大小申请 workspace为 0 则不需要 void* workspace nullptr; if (workspaceSize 0) { ret aclrtMalloc(workspace, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); } // 5. 第二段接口真正执行计算注意 executor 不可重复使用 ret aclnnReal(workspace, workspaceSize, executor, stream); // 6. 同步等待任务结束之后才能安全读结果 ret aclrtSynchronizeStream(stream); // 7. 释放全部资源tensor、device 内存、workspace、stream aclDestroyTensor(self); aclDestroyTensor(out); aclrtFree(selfAddr); aclrtFree(outAddr); if (workspaceSize 0) { aclrtFree(workspace); } aclrtDestroyStream(stream); aclrtResetDevice(deviceId); aclFinalize(); return ret ACL_SUCCESS ? 0 : 1; }写在最后aclnnReal 就是逐元素取实部这一件事两段式接口里第一段拿 workspaceSize 和 executor第二段拿它们去执行类型按配对表来、shape 保持一致即可。想继续深入可以看看 两段式接口、aclnn返回码 和 编译与运行样例算子源码与测试也都在 math/real 目录下。【免费下载链接】ops-math本项目是CANN提供的数学类基础计算算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-math创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑