news 2026/9/18 18:06:35

CANN opbase 单算子 API 整型数组入参创建:aclCreateIntArray 使用指南与源码解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CANN opbase 单算子 API 整型数组入参创建:aclCreateIntArray 使用指南与源码解析

CANN opbase 单算子 API 整型数组入参创建:aclCreateIntArray 使用指南与源码解析

【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase

本指南围绕 CANN opbase 仓库中单算子 API(aclnn 接口)的入参构造接口aclCreateIntArray,讲解其功能定位、函数原型、参数与返回值语义、生命周期管理,并结合仓库源码与单元测试剖析其内部实现与配套接口(aclDestroyIntArrayaclGetIntArraySize)的协作方式。读者读完可以掌握如何正确创建、使用与销毁aclIntArray,避免空指针、内存泄漏等常见问题,并理解它在单算子执行链路中的真实作用。

功能定位:单算子 API 的整型数组入参载体

在 CANN 算子库(CANN/opbase)的 aclnn 单算子执行框架中,aclIntArray是框架定义的一种用来管理和存储整型(int64_t)数据的数组结构。它作为单算子 API 执行接口的入参出现,典型场景包括:

  • 算子属性为整型数组类型时,例如shapedimsaxispaddingsize等以多个整数值表达的算子参数;
  • 将一组 Host 侧整型数据传递到算子执行接口(如GetWorkspaceSize与执行接口)中参与算子调度。

aclCreateIntArray负责创建这一对象,开发者无需关注其内部实现细节,只需保证传入的 Host 数据有效并妥善管理返回对象的生命周期即可。

接口声明位于 include/nnopbase/aclnn/acl_meta.h,其中将aclIntArray以不透明结构体(typedef struct aclIntArray aclIntArray;)的形式暴露给开发者,这正是"无需关注内部实现"的设计基础——外部只能通过本系列接口操作它。

函数原型与参数说明

aclCreateIntArray的函数原型为:

aclIntArray *aclCreateIntArray(const int64_t *value, uint64_t size)
参数名输入/输出说明
value输入Host 侧的int64_t类型指针,其指向的值会被拷贝给aclIntArray(创建后不再依赖原指针)。
size输入整型数组的长度,取值为正整数,即value指向的有效元素个数。

需要注意:

  • value指向的数据位于 Host 侧内存,接口内部会完成一次拷贝,因此创建后可以安全释放或复用原value缓冲区;
  • size表示的是数组元素个数而非字节数,{1, 1, 2, 3}的 size 为 4;
  • 该函数是纯 Host 侧内存管理接口,不涉及 Device 内存分配,也不依赖具体的算子实现。

返回值说明

  • 成功:返回创建好的aclIntArray对象指针;
  • 失败:返回nullptr(例如内部构造异常或参数非法导致分配失败时)。

调用方应在拿到返回值后立即判断是否为nullptr,再进行后续传参操作。

生命周期管理:与 aclDestroyIntArray 配套使用

aclIntArrayaclCreateIntArray创建,必须由 aclDestroyIntArray 接口销毁,二者配套使用,分别完成aclIntArray的创建与销毁:

aclnnStatus aclDestroyIntArray(const aclIntArray *array)

销毁接口的返回码语义为:返回0表示成功,返回其他值表示失败,返回码列表参见 公共接口返回码。

从源码实现看,销毁接口对空指针做了安全兜底:src/nnopbase/common/api/acl_op_api.cpp 中,array == nullptr时直接返回OK,不会触发崩溃;同时,当开启 aclnn 调试能力(op::internal::IsAclnnDebugEnabled())时,会通过CheckDoubleFree检查重复释放,并在检测到可能的 double-free 时输出告警日志"Possible double-free at addr %p."。这意味着:

  • 多次销毁同一对象在调试模式下会被记录告警,开发者应保证每个aclIntArray只被销毁一次;
  • nullptr调用销毁接口是安全的,可作为错误路径的收尾操作。

对应的单元测试也覆盖了这两个分支,见 tests/nnopbase/ut/composite_op/test_acl_op_api.cpp:

TEST_F(AclOpApiTest, aclIntArray) { int64_t values[] = {3, 4, 5}; auto* value = aclCreateIntArray(values, sizeof(values) / sizeof(values[0])); EXPECT_EQ(aclDestroyIntArray(value), OK); EXPECT_EQ(aclDestroyIntArray(nullptr), OK); }

配套查询接口:aclGetIntArraySize

创建之后,可以调用 aclGetIntArraySize 获取aclIntArray的大小(元素个数):

aclnnStatus aclGetIntArraySize(const aclIntArray *array, uint64_t *size)
参数名输入/输出说明
array输入输入的aclIntArray
size输出返回aclIntArray的大小(元素个数)。

其实现位于 src/nnopbase/common/api/acl_op_api.cpp,核心逻辑非常简洁:

aclnnStatus aclGetIntArraySize(const aclIntArray* array, uint64_t* size) { if (array == nullptr || size == nullptr) { return ACLNN_ERR_PARAM_NULLPTR; } *size = array->Size(); return OK; }

由此可知该接口的失败场景:当arraysize为空指针时返回161001ACLNN_ERR_PARAM_NULLPTR,空指针参数错误);测试用例对"空指针失败"与"正常取值"均有断言,见 tests/nnopbase/ut/composite_op/test_acl_op_api.cpp:

TEST_F(AclOpApiTest, aclGetIntArraySize) { EXPECT_NE(aclGetIntArraySize(nullptr, nullptr), OK); int64_t values[] = {3, 4, 5}; auto* value = aclCreateIntArray(values, sizeof(values) / sizeof(values[0])); uint64_t size = 0; EXPECT_EQ(aclGetIntArraySize(value, &size), OK); EXPECT_EQ(size, 3); // 元素个数为 3 EXPECT_EQ(aclDestroyIntArray(value), OK); }

调用示例:创建、传参与销毁的完整流程

以下代码来自 aclCreateIntArray 文档,展示了从创建到作为单算子 API 入参再到销毁的完整闭环,关键代码示例如下,仅供参考,不支持直接拷贝运行:

// 创建aclIntArray std::vector<int64_t> sizeData = {1, 1, 2, 3}; aclIntArray *size = aclCreateIntArray(sizeData.data(), sizeData.size()); ... // aclIntArray作为单算子API执行接口的入参 auto ret = aclxxXxxGetWorkspaceSize(srcTensor, size, ..., outTensor, ..., &workspaceSize, &executor); ret = aclxxXxx(...); ... // 销毁aclIntArray ret = aclDestroyIntArray(size);

配合查询接口的完整示例(来自 aclGetIntArraySize 文档):

// 创建aclIntArray std::vector<int64_t> valueData = {1, 1, 2, 3}; aclIntArray *valueArray = aclCreateIntArray(valueData.data(), valueData.size()); ... // 使用aclGetIntArraySize接口获取valueArray的大小 uint64_t size = 0; auto ret = aclGetIntArraySize(valueArray, &size); // 获取到的valueArray的size为4 ... // 销毁aclIntArray ret = aclDestroyIntArray(valueArray);

结合上述源码实现,可以总结出几条可落地的使用要点:

  1. 创建后及时判空aclCreateIntArray可能返回nullptr,传参前务必检查;
  2. 原缓冲区可复用:创建接口内部完成数据拷贝(new aclIntArray(value, size)),创建后原value数据源即可安全释放;
  3. vector.data()+vector.size()是最自然的构造方式,元素类型为int64_t,与size语义(元素个数)天然匹配;
  4. 成对创建与销毁:每个aclIntArray只销毁一次,销毁后不要再次使用,调试模式下重复释放会触发 double-free 告警;
  5. 空指针销毁安全aclDestroyIntArray(nullptr)直接返回成功,可作为统一清理逻辑的兜底。

源码纵深:aclIntArray 在单算子执行链路中的真实用途

aclIntArray虽然对开发者是不透明结构,但在框架内部会被广泛解析使用,可以从仓库源码中看到它的三类典型去向:

1. 作为算子属性参与 AICPU 任务构建

在 include/nnopbase/opdev/aicpu/aicpu_task.h 中,aclIntArray有两个用途:

  • AppendAttrForKey:逐个取出value->GetData()[i]参与执行缓存 key 的构建,即整型数组的每个元素都会被序列化进算子缓存键,用于区分不同参数取值下的缓存条目;
  • AddAicpuAttr:将整个aclIntArray作为 AICPU 算子的属性(attrName)添加到AicpuAttrs中下发。

这说明aclIntArray不仅是 Host 侧的普通容器,其内容会真实参与算子执行缓存命中与属性下发,参数的数值直接影响算子的调度与执行结果。

2. 作为 OpArg 统一参数载体

在 include/nnopbase/opdev/op_arg_def.h 中,aclIntArray*const aclIntArray*均可直接构造OpArgValue,从而进入统一的算子参数(OpArg)体系,与其他标量、张量、列表类型的入参走同一条参数收集与传递路径。

3. 支持从整型数组构造张量

在 src/nnopbase/common/utils/common_types.cpp 中,aclTensor提供了从aclIntArray出发的构造能力:

aclTensor::aclTensor(const aclIntArray* value, op::DataType dataType) : aclTensor(value->GetData(), value->Size(), dataType) {}

即整型数组数据可以直接转为一个指定数据类型的aclTensor(视图),进一步印证了aclIntArray在 Host 数据组织中的基础地位——它是整型标量数组在 aclnn 框架中的通用入口容器。

4. 执行缓存键构建

在 src/nnopbase/common/utils/op_cache.cpp 中,AddParamToBuf(const aclIntArray* value)会将整型数组内容写入缓存参数缓冲区,参与算子执行缓存的键值生成,与 AICPU 任务侧的AppendAttrForKey形成呼应,确保整型数组参数的取值变化能正确区分缓存条目。

小结

aclCreateIntArray是 CANN opbase 单算子 API 生态中最基础的 Host 侧入参构造接口之一:它通过不透明结构体隐藏内部实现,用一次数据拷贝保证调用方数据安全,并通过aclDestroyIntArrayaclGetIntArraySize两个配套接口完成生命周期闭环。框架内部则将其内容用于 AICPU 属性下发、执行缓存键构建、统一 OpArg 传参乃至张量视图构造。理解并规范使用这三个接口(创建、查询、销毁),是正确编写 aclnn 单算子调用代码的前提。

【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 18:04:32

LangChain 调 Ling-3.0-flash-Fin,TaoToken 接到 ChatOpenAI

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 18:03:19

MIND特征实现多模态医学图像配准的Python实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 18:00:56

YOLOv8医疗定制化改造:小目标癌细胞检测全栈方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 17:59:01

微电网风光储经济调度Matlab实现与优化

1. 项目背景与核心价值微电网作为分布式能源系统的重要形态&#xff0c;正在全球范围内加速普及。根据行业调研数据&#xff0c;2023年全球微电网市场规模已突破400亿美元&#xff0c;其中风光储一体化系统占比超过60%。这种系统面临的最大挑战是如何在可再生能源出力波动和负荷…

作者头像 李华