CANN应用开发入门样例

📅 2026/7/5 19:49:47
CANN应用开发入门样例
入门样例【免费下载链接】docs该仓库用于维护cann公共文档项目地址: https://gitcode.com/cann/docs样例功能本样例展示了如何使用CANN的Runtime API以及算子库中的Add算子实现向量加法运算out self alpha * other。Input vectors: self: [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0] other: [0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0] alpha: 1.0 Vector addition result: out: [1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.5, 12.0]编译及运行应用您可以单击Link获取完整样例代码同时该样例的README.md文件中也提供了编译和运行的指导。了解关键代码逻辑本节按照应用开发的顺序介绍样例代码的逻辑资源初始化 → 创建Stream → 准备输入 → 调用Add算子 → 输出结果 → 释放资源→ 资源去初始化。通过本节的介绍还可以帮助您了解CANN应用开发中关键API的功能这些关键API的接口名前缀为acl下文简称acl接口。资源初始化。// 初始化系统nullptr表示采用默认配置初始化系统调用其它acl接口前必须先初始化否则可能会导致后续系统内部资源初始化出错进而导致其它业务异常 aclInit(nullptr); // 指定计算设备 int32_t deviceId 0; aclrtSetDevice(deviceId);创建Stream。// Stream相当于一个任务队列任务按照进入队列的顺序依次执行 aclrtStream stream nullptr; aclrtCreateStream(stream);准备输入。根据Add算子的计算公式out self alpha * otherself和other为相加的两个输入向量alpha为系数out为相加后的结果向量。因此在准备输入时涉及创建两个输入Tensor、创建一个表示系数的Scalar、创建一个输出Tensor。在创建输入、输出Tensor时涉及申请Device内存存放输入或输出数据。定义一个创建Tensor的通用接口。template typename T int CreateAclTensor(const std::vectorT hostData, const std::vectorint64_t shape, void** deviceAddr, aclDataType dataType, aclTensor** tensor) { auto size GetShapeSize(shape) * sizeof(T); // 申请Device内存 aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); // 将输入数据从Host同步复制到Device aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); // 计算strides std::vectorint64_t strides(shape.size(), 1); for (int64_t i shape.size() - 2; i 0; i--) { strides[i] shape[i 1] * strides[i 1]; } // 创建Tensor *tensor aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), *deviceAddr); return 0; }创建输入、输出Tensor以及一个系数Scalar。std::vectorint64_t shape{8}; // 向量长度为8 void* selfDeviceAddr nullptr; void* otherDeviceAddr nullptr; void* outDeviceAddr nullptr; aclDataBuffer* outDataBuffer nullptr; aclTensor* self nullptr; aclTensor* other nullptr; aclTensor* out nullptr; aclScalar* alpha nullptr; std::vectorfloat selfHostData {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f}; // self向量输入数据 std::vectorfloat otherHostData {0.5f, 1.0f, 1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f}; // other向量输入数据 std::vectorfloat outHostData(8, 0.0f); float alphaValue 1.0f; // 系数值 // 创建输入 Tensor CreateAclTensor(selfHostData, shape, selfDeviceAddr, aclDataType::ACL_FLOAT, self); CreateAclTensor(otherHostData, shape, otherDeviceAddr, aclDataType::ACL_FLOAT, other); // 创建 alpha Scalar alpha aclCreateScalar(alphaValue, aclDataType::ACL_FLOAT); // 创建输出 Tensor CreateAclTensor(outHostData, shape, outDeviceAddr, aclDataType::ACL_FLOAT, out);调用Add算子。// 调用CANN内置的算子通常调用两段式接口 // 第一段接口aclnnAddGetWorkspaceSize该接口内部执行入参校验、在动态Shape场景下推导输出Shape、数据切块Tiling以及计算执行算子所需的workspace内存大小等任务 uint64_t workspaceSize 0; aclOpExecutor* executor nullptr; ret aclnnAddGetWorkspaceSize(self, other, alpha, out, workspaceSize, executor); // 第二段接口aclnnAdd执行算子计算接口内部涉及DFX例如Dump、溢出检测等、调用Runtime提供的LaunchKernel接口等 // workspaceAddr表示在Device侧申请的workspace内存地址 ret aclnnAdd(workspaceAddr, workspaceSize, executor, stream); // 同步等待任务完成 aclrtSynchronizeStream(stream);输出结果。将Device侧的结果数据回传到Host上。// outBufferAddr表示存放Device侧结果数据的内存地址 // resultData.data()表示存放Host侧数据的内存地址 aclrtMemcpy(resultData.data(), resultData.size() * sizeof(float), outBufferAddr, size * sizeof(float), ACL_MEMCPY_DEVICE_TO_HOST);释放资源。// 销毁Tensor和Scalar aclDestroyTensor(self); aclDestroyTensor(other); aclDestroyScalar(alpha); aclDestroyTensor(out); // 释放Device内存 aclrtFree(selfDeviceAddr); aclrtFree(otherDeviceAddr); aclrtFree(outDeviceAddr); aclrtFree(workspaceAddr); // 销毁Stream aclrtDestroyStream(stream);资源去初始化。// 复位设备 aclrtResetDeviceForce(deviceId); // 去初始化 aclFinalize();【免费下载链接】docs该仓库用于维护cann公共文档项目地址: https://gitcode.com/cann/docs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考