CANN opbase aclOpExecutor::AllocIntArray 接口详解:在算子执行器中安全分配整型数组属性
2026/9/19 11:31:45 网站建设 项目流程

CANN opbase aclOpExecutor::AllocIntArray 接口详解:在算子执行器中安全分配整型数组属性

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

导读

AllocIntArray是 CANN opbase 框架中aclOpExecutor执行器提供的基础内存分配接口,用于在算子执行流程中分配一个aclIntArray整型数组对象,并直接以调用方传入的int64_t数据完成初始化。它在算子开发中的典型应用场景包括:为 Transpose 算子构造维度重排参数perm、为卷积类算子准备strides/paddings/dilations等整型属性数组、为 memset 类算子携带填充值数组等。读完本文,你将掌握AllocIntArray的函数原型、参数语义、返回值与约束,理解其由执行器统一管理的生命周期模型,并能结合仓库源码与测试用例写出安全、可复用的调用代码。

函数原型与声明位置

AllocIntArrayaclOpExecutor的公开成员方法,其原型在仓库中的正式声明位于 include/nnopbase/opdev/op_executor.h:

aclIntArray* AllocIntArray(const int64_t* value, uint64_t size);

从声明所在的类结构可以看出,AllocIntArrayAllocFloatArrayAllocBoolArrayAllocTensorListAllocScalarList等接口并列,共同构成执行器的"参数对象分配族",专门用于在算子执行上下文中按类型创建各类参数容器对象(参见 op_executor.h)。

其中aclIntArray是一个不透明结构体类型,其类型声明位于 include/nnopbase/aclnn/acl_meta.h,属于 ACLNN 元数据类型家族(aclTensoraclScalaraclFloatArrayaclBoolArray等)的一员,底层封装了int64_t数据指针及其元素个数。

参数说明

参数输入/输出说明
value输入源数据指针,指向用于初始化aclIntArrayint64_t数据。接口内部会基于该内存中的数据完成数组拷贝与初始化。
size输入源数据中的元素个数,即待分配的aclIntArray的元素数量。

参数语义要点:

  • value指向的内存只需要在调用AllocIntArray期间有效即可,接口内部会复制数据,调用结束后调用方可以安全释放或复用该缓冲区;
  • size以"元素个数"为单位而非字节数,元素类型固定为int64_t(8 字节有符号整型);
  • 该接口与 C 语言风格的aclCreateIntArray(见 acl_meta.h)功能等价,是后者在aclOpExecutor对象上的面向对象封装版本。

返回值说明

  • 成功:返回新分配的aclIntArray指针;
  • 失败:返回nullptr

返回的指针在算子执行流程结束前始终有效,且不需要调用方手动释放(生命周期管理详见下文"内存生命周期"一节)。失败场景下,仓库实现会通过OP_LOGE记录错误日志,日志级别为ACLNN_ERR_INNER,便于问题定位。

约束说明

  • 输入指针不能为空value不能传入nullptr,空指针将导致接口内部构造aclIntArray失败并返回nullptr
  • size应与value指向的实际可用元素数一致,调用方需自行保证缓冲区边界,接口不会做越界检查;
  • 分配失败(如内存不足、构造异常)时接口返回nullptr,调用方应做空指针判空处理后再使用返回值。

底层实现与失败处理机制

AllocIntArray的实现位于 src/nnopbase/composite_op/aclnn_engine/op_executor.cpp,完整代码如下:

aclIntArray* aclOpExecutor::AllocIntArray(const int64_t* value, uint64_t size) { aclIntArray* array = nullptr; ADD_TRY_CATCH(array = new aclIntArray(value, size); allocatedObjList_.push_back(array); return array; , OP_LOGE(ACLNN_ERR_INNER, "aclOpExecutor::AllocIntArray failed."); delete array; return nullptr;); }

从源码结构可以提炼出三条关键实现事实:

  1. 对象构造即拷贝:接口通过new aclIntArray(value, size)完成对象的堆上创建,构造时即以valuesize初始化,因此数据在创建瞬间即被复制进数组对象内部;
  2. 异常安全ADD_TRY_CATCH宏包裹整个创建过程,任何异常(如内存分配失败)都会被捕获,此时先delete array清理半成品对象,再记录ACLNN_ERR_INNER级别的错误日志并返回nullptr,保证调用方拿到的要么是完整对象、要么是空指针,不存在悬垂中间状态;
  3. 执行器登记管理:创建成功后对象指针被追加进allocatedObjList_链表。该链表由aclOpExecutor持有,随执行器的析构统一销毁,这是理解本接口内存语义的关键(详见下文)。

内存生命周期:由执行器统一托管

AllocIntArray返回的aclIntArray对象不归调用方所有,而是登记在执行器内部的allocatedObjList_中,生命周期与aclOpExecutor实例绑定:

  • 无需手动释放:调用方不应(也无需)对返回值调用aclDestroyIntArray(该 C 接口声明于 acl_meta.h),对象会在执行器析构时统一回收;
  • 执行器内复用:同一执行器实例上多次调用AllocIntArray会累积登记多个对象,它们可以一并作为后续算子下发的参数使用,非常适合"先准备参数、再统一执行"的 aclnn 风格调用流程(如先AllocIntArray构造属性,再通过CommonOpExecutorRun发起执行);
  • 避免跨执行器混用:返回的数组指针应在同一执行器的生命周期与执行流程内使用,不要在其他执行器实例中引用。

这一"执行器统一托管"的设计与AllocTensorAllocScalar等接口完全一致(参见 op_executor.h),保证了算子参数对象与执行上下文的一致性,也显著降低了调用方手动管理内存出错的风险。

典型应用场景与完整示例

场景一:为 Transpose 算子构造维度重排参数 perm

aclIntArray最常见的用途之一是作为算子的整型属性参数。以 Transpose 算子为例,其维度重排顺序perm即支持aclIntArray*类型(参见 Transpose 算子文档),在调用侧通过AllocIntArray构造:

// 构造 perm 数组:把输入 tensor 的维度按 [1, 0, 2] 顺序重排 int64_t valuePerm[] = {1, 0, 2}; auto perm = executor->AllocIntArray(valuePerm, 3); if (perm == nullptr) { // 处理分配失败 return; }

场景二:为卷积类算子准备 strides / paddings / dilations

在仓库的二进制复用测试 tests/nnopbase/st/composite_op/test_binary_resuse.cpp 中,多个卷积类整型属性数组通过AllocIntArray一次性构造:

auto stridesIntArray = executor->AllocIntArray(strides, 4); auto paddingsIntArray = executor->AllocIntArray(paddings, 4); auto dilationsIntArray = executor->AllocIntArray(dilations, 4);

同一模式也出现在 test_debug_kernel.cpp 等测试用例中,印证了"执行器内批量分配多个整型数组作为算子属性"的标准用法。

场景三:DSA 任务中构造输出 shape

在 DSA(确定性计算加速)相关测试 test_dsa.cpp 中,AllocIntArray被用来把std::vector<int64_t>封装的维度数据转换成aclIntArray并作为输出 shape 参数传入:

auto outShape = executor->AllocIntArray(dims.data(), dims.size());

这里体现了dims.data()dims.size()直接作为valuesize参数的惯用法,std::vector<int64_t>与接口参数天然匹配。

场景四:memset 算子内部构造整型属性

在框架自身的 memset 执行路径 memset_op.cpp 中,AllocIntArray被用于把 memset 的整型填充值属性序列化为算子参数:

intAttrArray_ = executor->AllocIntArray(memsetIntAttrs_.data(), memsetIntAttrs_.size());

随后该数组与AllocTensorListAllocFloatArray的结果一同通过OP_ATTR(intAttrArray_, floatAttrArray_)组装进算子参数上下文,展示了AllocIntArray在框架内部算子参数组装链路中的真实作用。

场景五:与 ConvertToTensor 组合使用

aclOpExecutor还提供了配套的转换接口ConvertToTensor(const aclIntArray* value, op::DataType dataType)(见 op_executor.h),可将AllocIntArray分配的数组转换为aclTensor使用。在单测 tests/nnopbase/ut/composite_op/test_op_executor.cpp 中可以看到完整链路:

int64_t intValue[] = {1, 2, 3}; auto array3 = executor.AllocIntArray(intValue, 3); EXPECT_NE(array3, nullptr); auto tensor7 = executor.ConvertToTensor(array3, DataType::DT_INT64);

这也说明AllocIntArray并非孤立接口,而是执行器"整型数组 -> 张量"数据通路上的起点。

基础用法示例

以下示例完整复现原接口文档的用法,并补充了判空处理:

// 分配一个长度为 10 的 aclIntArray void Func(aclOpExecutor *executor) { int64_t myArray[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; aclIntArray *array = executor->AllocIntArray(myArray, 10); if (array == nullptr) { // 分配失败:记录日志并返回 return; } // array 可直接作为算子整型属性参数使用, // 无需手动释放,执行器析构时统一回收 }

测试验证与质量保障

仓库通过多层次的单元测试和系统测试对AllocIntArray的行为进行验证:

  • 基础分配验证:tests/nnopbase/ut/composite_op/test_op_executor.cpp 验证了分配后返回值非空(EXPECT_NE(array3, nullptr)),并随后通过ConvertToTensor完成类型转换验证;
  • 多数组批量分配:test_binary_resuse.cpp、test_debug_kernel.cpp 等用例验证了同一执行器内连续分配多个整型数组并组合使用的正确性;
  • 执行器生命周期绑定:test_dsa.cpp 等用例在uniqueExecutor场景下使用AllocIntArray,验证了对象随执行器销毁而被正确回收;
  • 多线程安全:test_op_kernel_multithread.cpp 在多线程执行场景下调用本接口,验证了其在并发环境下的可用性。

与 C 风格接口的对照

能力C++ 执行器接口C 风格接口(见 acl_meta.h)
创建整型数组executor->AllocIntArray(value, size)aclCreateIntArray(value, size)
销毁整型数组无需手动销毁,随执行器回收aclDestroyIntArray(array)
查询数组长度aclGetIntArraySize(array, &size)

在标准 aclnn 算子开发流程中,推荐优先使用AllocIntArray:它在提供同样分配能力的同时,借助执行器的统一生命周期管理免除了手动释放的负担,降低了内存泄漏与悬垂指针风险。

总结

AllocIntArray是 CANN opbase 中aclOpExecutor面向算子属性构造的基础设施接口,以"传入数据即初始化、执行器统一托管、失败返回空指针"三大特性,为算子开发者提供了安全、简洁的aclIntArray分配方式。结合仓库源码可以看到,其底层实现通过异常捕获保证失败路径无泄漏,通过allocatedObjList_登记机制实现与执行器绑定的生命周期管理,并被 Transpose、memset、卷积类算子及 DSA 任务广泛使用。掌握该接口的语义与生命周期规则,是编写健壮、可复用的 aclnn 算子调用代码的重要一环。

延伸阅读

  • 执行器接口总览:op_executor.md
  • 同类分配接口:AllocFloatArrayAllocBoolArrayAllocTensorListAllocScalarList(见 op_executor.h)
  • ACLNN 元数据类型与 C 风格创建/销毁接口:acl_meta.h
  • 整型数组在 aicpu 属性序列化中的使用:aicpu_task.h
  • 接口实现源码:op_executor.cpp

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询