新闻详情

新闻详情

首页 / 资讯中心 / 详情

CANN opbase 算子开发指南:aclOpExecutor::AllocScalarList 标量列表分配接口解析

发布时间:2026/9/19 5:43:59来源:尧图网络
CANN opbase 算子开发指南:aclOpExecutor::AllocScalarList 标量列表分配接口解析
CANN opbase 算子开发指南aclOpExecutor::AllocScalarList 标量列表分配接口解析【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase导读AllocScalarList是 CANN opbase 基础框架库中aclOpExecutor提供的内存分配接口之一用于在算子执行上下文中批量创建并初始化aclScalarList标量列表将多个aclScalar封装为一个整体对象供算子运行时的参数传递与缓存序列化使用。本文以 AllocScalarList 官方接口文档 为骨架结合 opbase 仓库的源码实现完整讲解该接口的函数原型、参数语义、返回值与约束并深入剖析其底层对象模型、内存生命周期管理与配套 C 接口帮助开发者在自定义算子尤其是动态 shape 场景中正确使用标量列表。一、接口概述在算子执行器中批量封装标量在 CANN 的 aclnn 算子开发模型中aclOpExecutor是算子执行器的核心对象负责算子参数对象tensor、标量、数组、列表等的分配与生命周期管理。其接口族包含AllocTensor、AllocScalar、AllocIntArray、AllocTensorList等而AllocScalarList用于把一组已创建的aclScalar对象聚合成一个aclScalarList。该接口对应的官方描述为Allocates an aclScalarList and specifies the aclScalars contained in it即分配一个aclScalarList并指定其中包含的aclScalar。典型应用场景是当算子的 attribute 本身是一个由多个标量构成的列表例如一组求和权重、一组阈值、多个维度的参数时无法用单个aclScalar表达需要借助aclScalarList统一传递。在接口族中AllocScalarList与AllocScalar是天然配套的先用 AllocScalar 逐一生成标量再用AllocScalarList打包。接口声明位于 op_executor.h与AllocTensorList、AllocIntArray、AllocFloatArray、AllocBoolArray等批量分配接口并列可见其在整个 executor 对象分配体系中的位置。二、函数原型与参数详解2.1 函数原型aclScalarList *AllocScalarList(const aclScalar *const *scalars, uint64_t size)该函数是aclOpExecutor的公有成员方法声明见 op_executor.h返回aclScalarList*指针。2.2 参数说明参数Input/Output描述scalarsInput源数据用于初始化 aclScalarList即待封装的 aclScalar 指针数组sizeInput源数据中元素的个数即标量个数要点说明scalars的类型是const aclScalar *const *即指向常量aclScalar*指针的常量指针意味着该接口不会修改传入的指针数组内容调用方可以安全地传入std::vectoraclScalar*::data()形式的指针size为uint64_t无符号 64 位整数表示源数据中元素的数量应严格等于scalars数组实际长度与返回aclTensorList的AllocTensorListop_executor.h用法一致二者共享同一套数组指针 元素个数的参数约定。三、返回值与使用约束3.1 返回值成功返回分配好的aclScalarList对象指针失败返回nullptr。从源码实现看op_executor.cpp内部通过ADD_TRY_CATCH宏包裹new aclScalarList(scalars, size)的构造过程任何异常例如内部memcpy_s拷贝失败抛出std::runtime_error都会被捕获并记录日志aclOpExecutor::AllocScalarList failed.随后释放对象并返回nullptraclScalarList* aclOpExecutor::AllocScalarList(const aclScalar* const* scalars, uint64_t size) { aclScalarList* list nullptr; ADD_TRY_CATCH(list new aclScalarList(scalars, size); allocatedObjList_.push_back(list); return list; , OP_LOGE(ACLNN_ERR_INNER, aclOpExecutor::AllocScalarList failed.); delete list; return nullptr;); }3.2 使用约束Restrictions官方文档明确给出约束输入指针不能为空The input pointer cannot be null即scalars不得传入nullptr。不过从 aclScalarList 构造函数实现 可以看出底层对空指针与零长度做了防御性处理当scalars ! nullptr size ! 0时才执行内存分配与拷贝当scalars为空或size为 0 时构造出的对象内部scalars_保持为nullptr、size_为 0。因此传入合法的非空指针数组是推荐用法符合文档约束传入空指针、零长度虽然不会导致崩溃对象仍可构造但得到的列表无实际内容调用Size()将返回 0调用GetData()将返回nullptr后续参与算子参数传递时可能无法满足算子对 attribute 的校验要求仍应在业务代码中避免。四、完整示例与运行说明官方文档给出了一个完整的示例初始化五个aclScalar并将其封装为一个aclScalarList。代码如下原文照录并补充注释// Initialize five aclScalars and encapsulate them into an aclScalarList. void Func(aclOpExecutor *executor) { int64_t val 5; std::vectoraclScalar * scalars; for (int64_t i 1; i 5; i) { aclScalar *scalar executor-AllocScalar(val); scalars.push_back(scalar); } aclScalarList *scalarList executor-AllocScalarList(scalars.data(), scalars.size()); }该示例的关键点标量生成循环中调用executor-AllocScalar(val)创建标量。AllocScalar具有大量按值重载覆盖int8_t/int16_t/int32_t/int64_t、uint8_t~uint64_t、float/double、fp16_t/bfloat16、bool等类型重载清单见 op_executor.h示例中传入int64_t会匹配AllocScalar(int64_t value)重载临时容器使用std::vectoraclScalar*暂存指针最后通过data()与size()提取裸指针数组和元素个数传入接口这正是该接口设计面向的常规用法返回值scalarList成功时为有效指针失败时为nullptr调用方需自行判断后再将其作为算子属性使用生命周期由于AllocScalar与AllocScalarList创建的对象均登记在 executor 内部示例中无需手动释放详见下一节。五、源码级原理aclScalarList 的对象模型与内存管理5.1 aclScalarList 数据结构aclScalarList定义于 common_types.h继承自op::Object核心成员为struct aclScalarList : public op::Object { // ... aclScalar* operator[](uint64_t i); const aclScalar* operator[](uint64_t i) const; uint64_t Size() const; const aclScalar* const* GetData() const; ge::AscendString ToString() const; // ... private: aclScalar** scalars_{nullptr}; uint64_t size_{0}; uint8_t reserved_field_[16]; private: aclScalarList(const aclScalar* const* scalars, uint64_t size); ~aclScalarList() override; };值得注意的设计细节构造函数与析构函数均为私有并声明aclOpExecutor为友元类friend class aclOpExecutor;。这意味着用户无法直接new一个aclScalarList只能通过aclOpExecutor::AllocScalarList或 C 接口aclCreateScalarList创建从类型系统层面保证了对象创建入口的唯一性提供operator[]下标访问、Size()获取元素个数、GetData()获取内部指针数组、ToString()生成可读字符串便于算子开发时校验与调试保留了 16 字节reserved_field_作为 ABI 兼容预留字段。5.2 构造时的深拷贝语义构造函数实现位于 common_types.cppaclScalarList::aclScalarList(const aclScalar* const* scalars, uint64_t size) { if (scalars ! nullptr size ! 0) { this-size_ size; this-scalars_ new (std::nothrow) aclScalar*[size]; OP_CHECK(memcpy_s(this-scalars_, size * sizeof(aclScalar*), scalars, size * sizeof(aclScalar*)) EOK, OP_LOGW(Failed to memcpy in aclScalarList create.), throw std::runtime_error(aclScalarList::aclScalarList memcpy runtime error.)); } }其语义要点使用new (std::nothrow)分配指针数组避免分配失败时抛出异常使用memcpy_s安全内存拷贝函数将传入的标量指针数组整体复制到对象内部因此列表持有的是 aclScalar 指针的副本而非引用外部数组。外部std::vector在调用返回后即可销毁aclScalarList的独立性不受影响拷贝的是指针数组而非标量本身标量对象的实际内存仍由各自创建者executor统一管理若memcpy_s失败会记录告警日志并抛出std::runtime_error该异常会被AllocScalarList中的ADD_TRY_CATCH捕获并转换为nullptr返回值。5.3 析构与生命周期归属aclScalarList析构函数common_types.cpp会将内部指针数组各元素置空后delete[]释放指针数组内存但不销毁各aclScalar对象本身——标量对象的生命周期由 executor 统一管理。关键点在于AllocScalarList在构造成功后立即执行allocatedObjList_.push_back(list)将对象登记到 executor 内部的allocatedObjList_容器定义见 op_executor.h。结合AllocScalar同样会把标量登记到该容器可以推断所有由aclOpExecutor分配的对象包括aclScalarList及其内部的aclScalar都归属 executor 统一管理随 executor 析构统一释放开发者在调用AllocScalarList后不需要也不应该手动释放返回的列表与其中的标量避免与 executor 的管理机制冲突造成重复释放对象内存由op::FVector框架自定义的快速向量容器管理默认容量为ALLOCATE_OBJ_DEFAULT_SIZE 128op_executor.h即 executor 默认可容纳约 128 个已分配对象而无需扩容批量创建标量与列表时具备较好的分配性能。六、与 C 接口的对应关系除 executor 成员方法外框架还提供了一组等价的 C 语言接口声明于 acl_meta.hC 接口功能aclScalarList* aclCreateScalarList(const aclScalar* const* value, uint64_t size)创建标量列表aclnnStatus aclDestroyScalarList(const aclScalarList* array)销毁标量列表aclnnStatus aclGetScalarListSize(const aclScalarList* scalarList, uint64_t* size)获取列表元素个数其中aclScalarList在 acl_meta.h 中以不透明结构体opaque struct形式对外暴露外部模块只能通过接口操作而不能直接访问内部成员。aclCreateScalarList与AllocScalarList均声明为aclScalarList的友元函数二者共享同一套私有构造入口。由此可以总结两条使用路径C 路径aclnn 算子实现内部通过aclOpExecutor::AllocScalarList创建对象归 executor 托管随 executor 释放适合在算子aclnnXxx接口实现函数中使用C 路径外部调用方/封装层通过aclCreateScalarList创建、aclDestroyScalarList销毁、aclGetScalarListSize查询由调用方显式管理生命周期适合在需要独立管理对象时使用。七、标量列表在参数传递与缓存中的作用aclScalarList不仅作为运行时参数载体还参与算子执行缓存cache的键值序列化。在 op_cache.h 中声明了void AddParamToBuf(const aclScalarList* scalars);AddParamToBuf系列函数会把各类参数tensor、scalar、列表等追加到缓存 key 的缓冲区中。当算子需要缓存执行结果即 executor 可重复运行时时aclScalarList中的每个标量值都会被序列化参与缓存键计算这意味着标量列表内容发生变化时缓存键随之变化从而保证不同标量参数组合下的算子执行不会误命中同一条缓存。这一机制说明AllocScalarList创建的对象在动态 shape、参数频繁变化的场景下其内容正确性是缓存正确性的前提。八、配套接口与更多参考AllocScalarList是aclOpExecutor对象分配接口族的成员相关接口索引参见 op_executor 接口总览常用配套接口包括AllocScalar创建单个标量是构造aclScalarList的前置步骤AllocTensorList创建 tensor 列表语义与AllocScalarList对称用于多个 tensor 的动态入参AllocIntArray、AllocFloatArray、AllocBoolArray创建整型/浮点/布尔数组用于数值数组类 attributeConvertToTensor将标量或数组转换为 tensor便于复用 tensor 类型化参数通路。此外opbase 仓库还提供了对应的中文接口文档 AllocScalarList中文版二者内容一致可按需查阅。九、使用建议与常见误区综合文档与源码给出以下工程建议先 AllocScalar 再 AllocScalarList列表中的标量应通过同一 executor 的AllocScalar创建保证全部对象登记在同一allocatedObjList_中生命周期统一size 必须与数组长度一致size传值错误会导致列表元素不完整或越界访问建议直接使用std::vector::size()不要手动释放executor 分配的对象由 executor 统一管理手动delete会与内部allocatedObjList_的析构逻辑冲突判空处理返回值接口在构造异常时返回nullptr将返回值作为算子属性使用前应进行判空利用 ToString 调试aclScalarList::ToString()会以逗号分隔打印各标量的字符串形式空元素打印nullptr可在算子 DFX/日志中快速核对列表内容实现见 common_types.cpp。结语AllocScalarList是 CANN opbase 中批量标量参数的标准封装入口从接口文档的函数原型、参数与约束出发结合 op_executor.cpp 的分配实现、common_types.h 的对象模型与 common_types.cpp 的构造析构逻辑可以完整理解该接口executor 统一分配、深拷贝指针数组、托管生命周期的底层机制。掌握它与AllocScalar、AllocTensorList及 C 接口aclCreateScalarList的协作关系有助于在算子开发中正确组织多标量属性并规避缓存序列化与内存管理层面的潜在问题。【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Server 2016 装 .NET 3.5 报 0x800F081F 离线排查 2026/9/19 6:38:25

Server 2016 装 .NET 3.5 报 0x800F081F 离线排查

Windows Server 2016 上要跑一套老业务系统,前置条件里写着"需要 .NET Framework 3.5",于是打开服务器管理器勾上角色和功能一路下一步,结果进度条走到一半弹出一条红字:安装一个或多个角色、角色服务或功能失败&#x…

阅读更多 →
Arm-Linux下Qt MQTT客户端框架搭建与优化实践 2026/9/19 6:38:25

Arm-Linux下Qt MQTT客户端框架搭建与优化实践

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

阅读更多 →
AS13004下的PFMEA与控制计划:航空航天供应链闭环质量实践 2026/9/19 6:38:25

AS13004下的PFMEA与控制计划:航空航天供应链闭环质量实践

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

阅读更多 →
平压印刷机课程设计:三个执行机构的运动协调与UG仿真解析 2026/9/19 6:38:25

平压印刷机课程设计:三个执行机构的运动协调与UG仿真解析

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

阅读更多 →
Next.js 15 项目实战:Claude Code 与 Codex 深度对比与选型指南 2026/9/19 6:38:25

Next.js 15 项目实战:Claude Code 与 Codex 深度对比与选型指南

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

阅读更多 →
Front-End-Checklist 之 First Contentful Paint(FCP)优化实战:从指标原理到 1.8 秒达标 2026/9/19 6:35:24

Front-End-Checklist 之 First Contentful Paint(FCP)优化实战:从指标原理到 1.8 秒达标

Front-End-Checklist 之 First Contentful Paint(FCP)优化实战:从指标原理到 1.8 秒达标 【免费下载链接】Front-End-Checklist 🗂 The essential checklist for modern web development, for humans and AI agents 项目地址: h…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞