GetWorkspaceSize:CANN opbase 中 L2 接口 workspace 大小的计算与查询指南

发布时间:2026/11/12 12:02:21

GetWorkspaceSize:CANN opbase 中 L2 接口 workspace 大小的计算与查询指南 GetWorkspaceSizeCANN opbase 中 L2 接口 workspace 大小的计算与查询指南【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase导读GetWorkspaceSize是 CANN opbase 算子库中aclOpExecutor提供的关键查询接口用于根据 L2二级接口组装阶段调用的各个 L0 算子计算整个 L2 接口实际运行时所需的 workspace工作内存大小。本文以 docs/zh/api/nnopbase/opdev/op_executor/Getworkspacesize.md 为主体结合 op_executor.h、op_executor.cpp、op_cache.cpp 及测试桩代码完整讲解接口原型、调用时机、底层计算原理、缓存机制并给出可直接套用的aclnnXxxGetWorkspaceSize实现模板。功能说明workspace 在 aclnn L2 接口中的作用在 CANN 的 aclnn 接口体系中一个融合的 L2 接口如aclnnAdd通常由多个 L0 算子组合而成。其中部分 L0 算子如需要中间结果暂存的算子在设备侧执行时需要额外的内存缓冲区这个缓冲区就称为 workspace工作内存。它由用户在 Host 侧通过aclrtMalloc分配并在执行阶段传给aclnnXxx接口。GetWorkspaceSize的核心职责是根据 L2 一阶段组装阶段中已调用的 L0 接口计算整个 L2 接口在运行阶段需要的 workspace 大小。这个大小既包括每个 L0 kernel 的 workspace 需求也包括中间张量中间结果在设备内存上的排布空间。从源码看GetWorkspaceSize是aclOpExecutor的公开成员函数声明位于 include/nnopbase/opdev/op_executor.h#L135uint64_t GetWorkspaceSize() const;函数原型与参数说明函数原型uint64_t GetWorkspaceSize()参数说明参数说明无该接口不接收任何参数结果直接从当前 executor 内部已组装好的信息kernel 启动对象列表、图结构、workspace 偏移等计算得到返回值说明返回uint64_t类型的 workspace 大小单位是字节返回值为 L2 接口在运行阶段需要的 workspace 大小在实际 L2 接口实现中该返回值通过出参uint64_t *workspaceSize暴露给调用者供其分配内存aclrtMalloc后在执行阶段把该内存指针传给运行接口使用。约束说明该接口本身无额外约束。需要注意的是它必须在 L2 一阶段组装阶段完成所有 L0 接口调用之后再调用否则计算结果不会包含后续新增 kernel 的 workspace 需求。这一点在下文调用时机小节中会结合源码详细说明。调用时机L2 一阶段 → GetWorkspaceSize → L2 二阶段GetWorkspaceSize的调用位置位于 L2 接口拆分的两个阶段之间L2 一阶段组装阶段调用CREATE_EXECUTOR()创建 executor通过ADD_TO_LAUNCHER_LIST_AICORE、ADD_TO_LAUNCHER_LIST_DSA等宏逐个添加 L0 kernel launcher并完成 shape 推导INFER_SHAPE查询阶段调用uniqueExecutor-GetWorkspaceSize()获得总 workspace 大小L2 二阶段运行阶段用户根据查询到的大小分配 workspace 内存调用aclnnXxx(void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, aclrtStream stream)执行其中aclnnXxx内部通过CommonOpExecutorRun真正下发任务。CREATE_EXECUTOR()宏定义于 include/nnopbase/opdev/make_op_executor.h#L19#define CREATE_EXECUTOR() UniqueExecutor(__func__)它创建一个UniqueExecutor对象内部持有std::unique_ptraclOpExecutor。UniqueExecutor的完整定义在 include/nnopbase/opdev/op_executor.h#L176-L208它在构造时记录当前函数名funcName_并提供get()、operator-、ReleaseTo()等接口。当 L2 一阶段结束时需要调用ReleaseTo(executor)把内部的aclOpExecutor所有权移交出去同时触发AddCache()注册缓存。调用示例aclnn 固定写法以下代码来自 Getworkspacesize.md 中的官方示例展示了GetWorkspaceSize在 aclnn L2 接口中的标准使用方式// aclnn固定写法 void aclnnAddGetWorkspaceSize(..., uint64_t *workspaceSize, aclOpExecutor **executor) { auto uniqueExecutor CREATE_EXECUTOR(); ...... *workspaceSize uniqueExecutor-GetWorkspaceSize(); }将这段模板展开成完整的 L2 一阶段实现并结合ReleaseTo移交 executor可以得到可运行的结构aclnnStatus aclnnAddGetWorkspaceSize(const aclTensor* x1, const aclTensor* x2, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor) { auto uniqueExecutor CREATE_EXECUTOR(); // 1. 添加 L0 kernel 到 executor含 shape 推导、workspace 偏移记录 ADD_TO_LAUNCHER_LIST_AICORE(Add, ...); // 2. 计算总 workspace 大小 *workspaceSize uniqueExecutor-GetWorkspaceSize(); // 3. 移交 executor 所有权注册缓存 uniqueExecutor.ReleaseTo(executor); return ACLNN_SUCCESS; }在仓库测试桩 tests/nnopbase/common/depends/op/aclnn_mul_stub.cpp#L40-L58 中可以找到完全一致的实现范式aclnnStatus aclnnMulStubGetWorkspaceSize(const aclTensor* intput1, const aclTensor* intput2, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor) { ... *workspaceSize uniqueExecutor-GetWorkspaceSize(); ... } aclnnStatus aclnnMulStub(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, const aclrtStream stream) { ... return CommonOpExecutorRun(workspace, workspaceSize, executor, stream); }这验证了一阶段查大小、二阶段跑任务的完整闭环aclnnMulStubGetWorkspaceSize负责查询大小aclnnMulStub负责携带workspace与workspaceSize调用CommonOpExecutorRun。底层原理workspace 大小是如何计算的GetWorkspaceSize的实现位于 src/nnopbase/composite_op/aclnn_engine/op_executor.cpp#L610-L627uint64_t aclOpExecutor::GetWorkspaceSize() const { if (impl_-GetWorkspaceSize() ! 0) { return impl_-GetWorkspaceSize(); } auto graph (op::mem::KernelGraph*)(impl_-GetGraph()); auto tensors graph-GetSortedKernelTensors(); OP_LOGD(Workspace tensor count: %zu., tensors.size()); auto allocator op::mem::MaxAllocator(); workspaceDeviceAicpuTaskOffset_ allocator.Allocate(tensors); uint64_t workspaceSize workspaceDeviceAicpuTaskOffset_ workspaceDeviceAicpuMem_; if (impl_-GetOpExecCache() ! nullptr) { impl_-OpExecCacheSetWorkspaceSize(workspaceSize); } OP_LOGD(workspaceSize_:%lu, workspaceDeviceAicpuTaskOffset_:%lu, workspaceSize, workspaceDeviceAicpuTaskOffset_); return workspaceSize; }其计算逻辑分为三步优先复用已缓存结果如果OpExecutorImpl中已经记录过 workspace 大小非 0直接返回避免重复计算内存分配器计算从 executor 内部的KernelGraph取出已排序的 kernel 张量列表GetSortedKernelTensors使用op::mem::MaxAllocator对这些张量在 workspace 内做内存分配得到workspaceDeviceAicpuTaskOffset_汇总返回总大小 张量排布偏移workspaceDeviceAicpuTaskOffset_ AICPU 任务区大小workspaceDeviceAicpuMem_。这两个成员定义于 include/nnopbase/opdev/op_executor.h#L165-L166。与之对应的GetLinearWorkspaceSizeop_executor.cpp#L629-L646使用LinearAllocator做线性排布适用于对内存复用要求更严格的场景。与 UpdateTensorAddr 的配合aclOpExecutor还提供UpdateTensorAddr(void* workspaceAddr, const size_t size)op_executor.cpp#L368-L384。在运行阶段拿到用户分配的 workspace 地址后它会通过SetWorkspaceAddr记录 workspace 基地址遍历allocatedTensorList_将所有IsFromWorkspace()为真的张量按各自的GetWorkspaceOffset()偏移把存储地址设置为workspaceAddr offset同步设置张量数据大小并更新 executor 记录的 workspace 大小。也就是说GetWorkspaceSize负责算多大UpdateTensorAddr负责把 workspace 中的中间张量指到对应位置两者配合完成了 workspace 从查询到使用的完整链路。缓存场景下的 workspace 查询当 executor 命中缓存PTAGetExecCache/PTAFindExecCache时workspace 大小直接从缓存对象获取见 op_executor.cpp#L912-L935 与 op_cache.cpp#L1073-L1075uint64_t OpExecCache::GetWorkspaceSize() const { return workspaceSize_; }workspaceSize_是在首次计算时通过OpExecCacheSetWorkspaceSizeop_executor.cpp#L312-L315写入缓存的。这保证了重复执行同一算子时repeatable 场景无需重新计算 workspace直接复用首次查询得到的大小即可。二阶段运行workspace 的校验与使用运行接口CommonOpExecutorRunop_executor.cpp#L962对 workspace 参数有严格的空指针校验if (unlikely(executor nullptr)) { OP_LOGE(ACLNN_ERR_PARAM_NULLPTR, The executor is nullptr.); return ACLNN_ERR_PARAM_NULLPTR; } if (unlikely(workspaceSize 0 workspace nullptr)) { OP_LOGE(ACLNN_ERR_PARAM_NULLPTR, The workspace is nullptr.); DeleteExecutorForError(executor); return ACLNN_ERR_PARAM_NULLPTR; }即当GetWorkspaceSize返回的大小大于 0 时二阶段必须传入有效的 workspace 内存指针否则返回ACLNN_ERR_PARAM_NULLPTR错误。这是使用者最容易忽略的约束务必保证一阶段查询的大小与二阶段实际分配的内存大小一致。在自定义算子与复杂场景中的应用对于需要多段 workspace 的复杂场景如aclnn_bninference_d_kernel测试桩 aclnn_bninference_d_kernel_stub.cpp一阶段查询出的workspaceSize还可以在二阶段被拆分使用。例如在 aclnn_bninference_d_kernel_stub.cpp#L174-L198 中先比较不同子接口的 workspace 大小取较大值再在二阶段从同一块 workspace 中划分子区段if (viewcopyWsSize *workspaceSize) { *workspaceSize viewcopyWsSize; } *workspaceSize inContWorkspaceSize; ... workspaceSize - inContWorkspaceSize; void* inWorkspace (char*)workspace workspaceSize;这表明GetWorkspaceSize返回的大小是整块可用空间的上界二阶段实现可以在该空间内自行规划多个子缓冲区的布局。总结与最佳实践GetWorkspaceSize必须在 L2 一阶段完成所有 L0 kernel 添加之后调用其结果才完整返回值以字节为单位的uint64_t用于指导调用方分配 workspace 内存若返回大小大于 0二阶段必须传入对应大小的有效 workspace 指针否则运行接口会报ACLNN_ERR_PARAM_NULLPTR底层通过MaxAllocator对图中 kernel 张量做内存排布并叠加 AICPU 任务区大小得到总大小已缓存场景直接复用缓存值避免重复计算实现 L2 接口时请严格遵循CREATE_EXECUTOR()→ 添加 L0 →GetWorkspaceSize()→ReleaseTo(executor)→ 二阶段CommonOpExecutorRun的固定范式。相关参考接口声明include/nnopbase/opdev/op_executor.h宏与启动工具include/nnopbase/opdev/make_op_executor.h核心实现src/nnopbase/composite_op/aclnn_engine/op_executor.cpp缓存实现src/nnopbase/common/utils/op_cache.cpp测试桩示例tests/nnopbase/common/depends/op/aclnn_mul_stub.cpp、tests/nnopbase/common/depends/op/aclnn_bninference_d_kernel_stub.cpp【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/12 12:02:20

PyTorch模型迁移昇思MindSpore实战:结构、权重与算子转换全解析

前阵子有个做推荐系统的朋友找到我,说他们花了大半年训练的一版模型,因为客户机房换成了昇腾系列硬件,整个部署方案都要重做。模型本身是PyTorch写的,想在昇思MindSpore上跑起来,第一关就卡在模型转换上——转出来的脚…

2026/11/11 6:24:31

系统提示词工程指南:从合集拆解到模块化写作与版本管理

system_prompts_leaks 这个标题第一次出现在我视野里的时候,我正在给一个内部客服助手重写系统提示词(system prompts)。当时最头疼的不是模型能力不够,而是我不知道"工业级的写法长什么样"——自己憋出来的规则条目东一…

2026/11/12 6:42:45

信息化战略规划全流程拆解:目标、诊断、架构与落地

简介:这份PDF文档系统梳理了企业信息化战略规划报告的关键撰写要点,面向企业信息化负责人、战略规划人员及管理咨询顾问,可帮助解决规划框架不清晰、内容不完整、目标与原则脱节等常见问题。文档从规划目标、规划原则、规划内容到工作方式逐层…

2026/11/12 12:00:52

辽源市电工证怎么网上查询?外省证能不能转过来

辽源市电工证怎么网上查询?外省证能不能转过来 之前考的证在外省能不能转过来?这几乎是所有打算在辽源市从事电工相关工作的朋友最关心的问题。特别是在当前国家对特种作业操作证要求越来越严格的背景下, 辽源市电工证…

2026/11/12 12:00:52

柳市低压电工证怎么考报名流程全攻略

柳市低压电工证怎么考报名流程全攻略 你是不是正愁不知道 柳市低压电工证怎么报名 ?怕被那些乱收费的中介坑了?别急,这篇文章就是为你准备的,从头到尾讲清楚怎么考,怎么避坑,省心又省钱。…

2026/11/12 12:00:51

广安岳池安监局电工证千万别踩坑,这3步教你避雷

广安岳池安监局电工证千万别踩坑,这3步教你避雷 不知道去哪报名怕被中介坑?现在很多人在办理【广安岳池安监局电工证】时,最大的顾虑就是怕被中介坑,花冤枉钱还拿不到证。其实只要掌握正确的方法,避坑并不是难事。下面我们就来聊聊关于广安岳池安监局电…

2026/11/12 11:55:51

桥东区电工证怎么考通过率揭秘 电工忙到没空复习也能过?

桥东区电工证怎么考通过率揭秘 电工忙到没空复习也能过? 工地太忙根本没时间复习考试,这是很多一线电工的普遍心声。你可能正在洛阳涧西区的房建工地上,每天扛着工具穿梭在钢筋水泥之间,连吃饭时间都得抢。但你知道吗? 桥东区电工证怎么考…

2026/11/11 12:42:59

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/12 0:04:01

工地太忙根本没时间复习考试?学习电工证到哪里学通过率揭秘

工地太忙根本没时间复习考试?学习电工证到哪里学通过率揭秘 工地太忙根本没时间复习考试?你不是一个人。作为一名在南阳卧龙区干了七八年市政公用工程的电工,我深知这个问题的现实性。电工证不仅是工作的“入场券”,更是职业发展的“通行证”,但备考过程…

2026/11/12 0:04:01

双流电工证考别怕挂科!郑州报考避坑指南全攻略

双流电工证考别怕挂科!郑州报考避坑指南全攻略 实操考试心里没底怕挂科?双流电工证考在郑州报名,很多人因为不了解流程、准备不充分,白白浪费时间和金钱。作为三门峡应届工程类毕业生,我也曾经历过这样的焦虑。今天就从零开始,手把手教你如何避开郑州报…

2026/11/12 0:04:01

之前考的证在外省能不能转过来 怎么报名考电工证培训价格多少

之前考的证在外省能不能转过来 怎么报名考电工证培训价格多少 之前考的证在外省能不能转过来?这个问题确实让不少准备换城市工作的朋友犯了难,尤其像电工证这种实操性很强的证书,很多人担心跨省后证书能不能继续用。其实,只要符合相关流程,是可以顺利转…

2026/11/11 20:27:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/12 9:51:42

SSM电子书店源码全解析:结构、原理、部署与排错实战

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

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑