十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

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

CANN opbase 单算子 API 整型数组入参创建:aclCreateIntArray 使用指南与源码解析 CANN opbase 单算子 API 整型数组入参创建aclCreateIntArray 使用指南与源码解析【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase本指南围绕 CANN opbase 仓库中单算子 APIaclnn 接口的入参构造接口aclCreateIntArray讲解其功能定位、函数原型、参数与返回值语义、生命周期管理并结合仓库源码与单元测试剖析其内部实现与配套接口aclDestroyIntArray、aclGetIntArraySize的协作方式。读者读完可以掌握如何正确创建、使用与销毁aclIntArray避免空指针、内存泄漏等常见问题并理解它在单算子执行链路中的真实作用。功能定位单算子 API 的整型数组入参载体在 CANN 算子库CANN/opbase的 aclnn 单算子执行框架中aclIntArray是框架定义的一种用来管理和存储整型int64_t数据的数组结构。它作为单算子 API 执行接口的入参出现典型场景包括算子属性为整型数组类型时例如shape、dims、axis、padding、size等以多个整数值表达的算子参数将一组 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 配套使用aclIntArray由aclCreateIntArray创建必须由 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.cppTEST_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; }由此可知该接口的失败场景当array或size为空指针时返回161001ACLNN_ERR_PARAM_NULLPTR空指针参数错误测试用例对空指针失败与正常取值均有断言见 tests/nnopbase/ut/composite_op/test_acl_op_api.cppTEST_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::vectorint64_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::vectorint64_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);结合上述源码实现可以总结出几条可落地的使用要点创建后及时判空aclCreateIntArray可能返回nullptr传参前务必检查原缓冲区可复用创建接口内部完成数据拷贝new aclIntArray(value, size)创建后原value数据源即可安全释放用vector.data()vector.size()是最自然的构造方式元素类型为int64_t与size语义元素个数天然匹配成对创建与销毁每个aclIntArray只销毁一次销毁后不要再次使用调试模式下重复释放会触发 double-free 告警空指针销毁安全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 侧入参构造接口之一它通过不透明结构体隐藏内部实现用一次数据拷贝保证调用方数据安全并通过aclDestroyIntArray、aclGetIntArraySize两个配套接口完成生命周期闭环。框架内部则将其内容用于 AICPU 属性下发、执行缓存键构建、统一 OpArg 传参乃至张量视图构造。理解并规范使用这三个接口创建、查询、销毁是正确编写 aclnn 单算子调用代码的前提。【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表