资讯动态

CANN opbase 单算子 API 深度解析:aclGetScalarListSize 获取 aclScalarList 尺寸

发布时间:2026/9/18 6:28:53 来源:尧图企业网站定制
CANN opbase 单算子 API 深度解析aclGetScalarListSize 获取 aclScalarList 尺寸【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase本篇围绕 CANN opbase 仓库中单算子aclnnAPI 的元数据接口aclGetScalarListSize展开先继承官方 API 文档中对该接口的函数定义、原型、参数与错误码说明再结合 opbase 仓库中的头文件声明、实现源码与相邻接口剖析aclScalarList这一容器抽象的尺寸语义、所有权模型以及与aclCreateScalarList、aclDestroyScalarList构成的完整生命周期帮助读者在自定义算子开发中正确查询并管理标量列表。接口功能定位根据 API 文档aclGetScalarListSize用于获取通过aclCreateScalarList创建的aclScalarList的尺寸即列表中存储的aclScalar元素个数。从源码结构看该接口属于 opbase 对外暴露的 ACL 元数据metaAPI 家族之一。其声明位于 acl_meta.h与张量、数组、列表的创建/销毁/查询接口集中声明在同一头文件中并包裹在extern C块内typedef struct aclScalarList aclScalarList; // L31不透明句柄的前向声明 ACL_FUNC_VISIBILITY aclScalarList* aclCreateScalarList(const aclScalar* const* value, uint64_t size); // L46 ACL_FUNC_VISIBILITY aclnnStatus aclDestroyScalarList(const aclScalarList* array); // L54 ACL_FUNC_VISIBILITY aclnnStatus aclGetScalarListSize(const aclScalarList* scalarList, uint64_t* size); // L67文档同时强调了一个对使用者很友好的设计点引自 aclCreateScalarList.mdaclScalarList是框架定义、用于管理和存储多个标量的列表结构开发者“可以无需了解其内部实现即可使用它”。aclGetScalarListSize正是这种“黑盒容器”对外暴露的少数只读查询入口之一。函数原型与参数说明原型aclnnStatus aclGetScalarListSize(const aclScalarList *scalarList, uint64_t *size)其中返回类型aclnnStatus在 acl_meta.h 中定义为int32_t成功状态OK为0typedef int32_t aclnnStatus; constexpr aclnnStatus OK 0;参数官方文档给出的参数语义如下参数方向说明scalarList输入输入的aclScalarList句柄由aclCreateScalarList返回。size输出aclScalarList的尺寸元素个数。结合实现源码 acl_op_api.cpp 可以进一步确认两点语义细节aclnnStatus aclGetScalarListSize(const aclScalarList* scalarList, uint64_t* size) { if (scalarList nullptr || size nullptr) { return ACLNN_ERR_PARAM_NULLPTR; } *size scalarList-Size(); return OK; }两个入参都参与空指针校验scalarList或size任一为nullptr都会直接失败不会写入任何值尺寸来源返回值取自容器内部维护的元素个数即创建时通过aclCreateScalarList(value, size)传入的size本接口只读取、不修改列表内容。返回值与错误码官方文档的返回约定为成功返回0否则返回失败状态码详见 Common API Return Codes。文档同时指出了唯一列出的可能原因若返回错误码161001表示scalarList或size是空指针。该错误码在仓库错误码头文件 op_errno.h 中有明确定义#define ACLNN_ERR_PARAM_NULLPTR 161001结合通用返回码表见 common_api_return_codes.md错误码宏名含义0ACLNN_SUCCESS成功。161001ACLNN_ERR_PARAM_NULLPTR参数校验错误参数中存在无效的nullptr。161002ACLNN_ERR_PARAM_INVALID参数校验错误如数据类型推导不满足要求。从上述实现看aclGetScalarListSize是一条“纯查询”路径没有内存分配、没有跨层调用因此其唯一的失败分支就是 161001 空指针错误。实际排障时若遇到 161001优先检查是否把未创建创建失败返回nullptr的aclScalarList句柄、或未初始化的uint64_t地址传入了接口。aclScalarList 的容器模型与尺寸语义为了理解Size()到底代表什么有必要看一下aclScalarList在 opbase 内部的真实形态。它定义在 common_types.hstruct aclScalarList : public op::Object { friend class aclOpExecutor; friend aclScalarList* aclCreateScalarList(const aclScalar* const* value, uint64_t size); friend aclnnStatus aclDestroyScalarList(const aclScalarList* array); public: aclScalar* operator[](uint64_t i); // 按索引访问元素 const aclScalar* operator[](uint64_t i) const; uint64_t Size() const; // aclGetScalarListSize 的取值来源 const aclScalar* const* GetData() const; // 底层元素指针数组起始地址 private: aclScalar** scalars_{nullptr}; uint64_t size_{0}; uint8_t reserved_field_[16]; // 构造/析构为 private仅允许通过 aclCreateScalarList/aclDestroyScalarList 访问 };由此可以得出几个关键结论尺寸是创建时固定的size_在aclCreateScalarList(value, size)构造时由入参size写入容器本身不支持动态增删元素aclGetScalarListSize读到的就是“创建时拷贝进来的aclScalar指针个数”。列表存储的是aclScalar指针的拷贝与文档 aclCreateScalarList.md 的描述一致——“数组中的aclScalar指针按顺序被拷贝到aclScalarList中”。构造函数是 private 的外部只能通过 C 接口aclCreateScalarList分配对象这保证了句柄生命周期全部经过框架管理的创建/销毁配对。与销毁接口的所有权关系Size()并不只是一个“查询便利函数”。在实现源码中销毁接口 aclDestroyScalarList 的清理循环直接依赖它aclnnStatus aclDestroyScalarList(const aclScalarList* array) { if (array nullptr) { return OK; } // ...调试模式下双重释放检查CheckDoubleFree... for (uint64_t i 0; i array-Size(); i) { aclDestroyScalar((*array)[i]); // 逐个销毁列表内的每个 aclScalar } delete array; // 再销毁列表容器本身 return OK; }这说明aclDestroyScalarList会连同列表内的每个aclScalar元素一起销毁即容器对其元素拥有所有权。由此可以推断出两条工程实践通过aclCreateScalar创建的标量一旦装入aclScalarList就不应再对同一aclScalar单独调用aclDestroyScalar否则构成重复释放若需要校验“装进去的个数”是否正确例如拼多标量参数时防止少装/多装在创建之后、执行单算子 API 之前调用一次aclGetScalarListSize做断言是成本低且可靠的自检手段。完整使用示例官方示例引自 aclGetScalarListSize.md如下注意文档声明“以下代码示例仅供参考不用于直接复制执行”// Create an aclScalarList. std::vectoraclScalar * tempscalar{alpha1, alpha2}; aclScalarList *scalarList aclCreateScalarList(tempscalar.data(), tempscalar.size()); ... // Obtain the size of the scalarList. uint64_t size 0; auto ret aclGetScalarListSize(scalarList, size); // The obtained size of the scalarList is 2. ... // Destroy the aclScalarList. ret aclDestroyScalarList(scalarList);将 aclCreateScalarList.md 中的标量创建步骤合并进来可以还原出一段更完整的典型生命周期aclScalarList常作为单算子 API 的标量参数列表使用例如aclxxXxxGetWorkspaceSize/aclxxXxx的入参// 1. 创建两个 float 标量 float alpha1Value 1.2f; aclScalar *alpha1 aclCreateScalar(alpha1Value, aclDataType::ACL_FLOAT); float alpha2Value 2.2f; aclScalar *alpha2 aclCreateScalar(alpha2Value, aclDataType::ACL_FLOAT); // 2. 创建 aclScalarList拷贝 alpha1、alpha2 两个指针 std::vectoraclScalar * tempscalar{alpha1, alpha2}; aclScalarList *scalarList aclCreateScalarList(tempscalar.data(), tempscalar.size()); if (scalarList nullptr) { // aclCreateScalarList 失败时返回 nullptr后续所有接口都应跳过 // 各 aclCreateScalar 失败路径需单独兜底处理 } // 3. 查询尺寸并校验本文主角接口 uint64_t size 0; auto ret aclGetScalarListSize(scalarList, size); // 成功返回 0 if (ret 0 size ! 2) { // size 应与创建时传入的个数一致不一致说明使用方式有误 } // 4. 作为单算子 API 的输入参数执行 // auto ret aclxxXxxGetWorkspaceSize(srcTensor, scalarList, ..., outTensor, ..., workspaceSize, executor); // ret aclxxXxx(...); // 5. 销毁列表及其内部的 aclScalar 一并释放 ret aclDestroyScalarList(scalarList);从创建接口 aclCreateScalarList 的实现看创建失败内部new抛异常时会打印错误日志并返回nullptr因此第 2 步的空指针判断是后续调用aclGetScalarListSize前的必要前提——否则必然触发 161001。同族查询接口速览aclGetScalarListSize不是孤立接口它属于一组“列表/数组尺寸查询”API实现集中在 acl_op_api.cpp实现模式完全一致空指针校验 读取Size()接口对象声明位置aclGetIntArraySizeaclIntArrayacl_meta.haclGetFloatArraySizeaclFloatArrayacl_meta.haclGetBoolArraySizeaclBoolArrayacl_meta.haclGetTensorListSizeaclTensorListacl_meta.haclGetScalarListSizeaclScalarListacl_meta.h掌握其中之一的用法后其余接口的调用方式、空指针错误码161001与返回约定可以完全类推。小结aclGetScalarListSize是 opbase 单算子 API 元数据接口的只读查询入口原型为aclnnStatus aclGetScalarListSize(const aclScalarList*, uint64_t*)成功返回 0唯一文档化错误路径是 161001ACLNN_ERR_PARAM_NULLPTR对应scalarList或size为空指针定义见 op_errno.h从源码结构看其返回值取自aclScalarList::Size()即创建时通过aclCreateScalarList固定的元素个数销毁接口aclDestroyScalarList同样基于该尺寸对列表内全部aclScalar做级联释放因此容器对元素拥有所有权在自定义算子开发中创建列表后调用一次本接口做尺寸自检、并严格遵循“aclCreateScalarList创建 →aclGetScalarListSize查询 →aclDestroyScalarList销毁”的配对模式即可避免重复释放与尺寸错配类问题。【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

免费获取报价