asc-devkit 算子 Tiling 调试指南:ContextBuilder::Workspace 接口原理与实战用法 人工智能深度学习算子库CANNAscend【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址https://gitcode.com/cann/asc-devkit点击查看免费下载导读在 CANN asc-devkit 算子开发流程中Tiling 函数TilingFunc需要基于gert::TilingContext完成数据切分策略计算而 workspace工作内存往往需要在 Tiling 阶段就确定大小并传递给 Kernel 侧使用。本文聚焦context_ascendc::ContextBuilder::Workspace()接口讲解它如何将gert::ContinuousVector类型的工作内存指针注入 TilingContext并结合 ContextBuilder 头文件声明、底层实现 与 单元测试 给出可直接落地的完整调用范式帮助你正确使用该接口验证 Tiling 函数规避未定义行为。一、接口定位ContextBuilder 家族中的 WorkspaceContextBuilder是 asc-devkit 提供的一个链式构造器类用于在 Host 侧手动构造 TilingContext 来验证 Tiling 函数或构造 KernelContext 用于 TilingParse 函数的验证参见 ContextBuilder 简介。从 context_builder.h 的类声明 可以看出ContextBuilder的接口按用途分成两组Kernel Context 构造组Inputs()、Outputs()、BuildKernelRunContext()Tiling Context 构造组CompileInfo()、PlatformInfo()、AddPlatformInfo()、TilingData()、Workspace()、BuildTilingContext()以及更早配置阶段的NodeIoNum()、SetOpNameType()、IrInstanceNum()、AddInputTd()、AddOutputTd()、AddAttr()。Workspace()属于Tiling Context 构造组其作用是把指向gert::ContinuousVector的指针写入 TilingContext供 Tiling 函数在运行时读取工作内存相关信息。它的声明位置紧邻BuildTilingContext()context_builder.h 第 112-113 行这与其必须在BuildTilingContext()之前调用的约束相呼应。二、函数原型与参数详解函数原型ContextBuilder Workspace(gert::ContinuousVector *workspace)参数说明参数输入/输出说明workspace输入指向gert::ContinuousVector类的指针用于描述算子运行期间所需的工作内存gert::ContinuousVector是 gertGraph Engine Runtime中表示连续向量数据的容器类型。在测试代码中它通过工厂方法创建auto workspace_size_holder gert::ContinuousVector::Createsize_t(4096); auto ws_size reinterpret_castgert::ContinuousVector*(workspace_size_holder.get());见 test_tiling.cpp 第 46-47 行CreateT(capacity)会分配一段可容纳指定容量元素的内存返回的智能指针再被 reinterpret_cast 成gert::ContinuousVector*传给Workspace()。这里传入的实际上是workspace 尺寸信息的承载容器Tiling 函数可以通过该指针查询工作内存的字节数等元数据从而在 TilingData 中写出正确的切分参数。返回值说明返回当前ContextBuilder对象的引用这是 Builder 模式的典型设计保证可以继续链式调用后续方法例如ContextBuilder() .Workspace(ws_size) // 返回值仍是 ContextBuilder .BuildTilingContext(); // 继续链式调用三、约束说明为什么必须搭配 BuildTilingContext()原文档明确指出一个关键约束由于 TilingContext 与 KernelContext、TilingParseContext 内部数据排序不同Workspace()只支持以调用BuildTilingContext()为前提来使用其他场景建议用Outputs接口否则发生未定义行为。这一点从源码结构可以得到印证在 context_builder_impl.cpp 的 ContextBuilderImpl::Workspace 实现 中Workspace()将指针直接转发给Tiling 专用的底层构造器void ContextBuilderImpl::Workspace(gert::ContinuousVector* workspace) { ASCENDC_ASSERT(tilingCtxBuilder_ ! nullptr, return, CXT_ASCENDC_LOGE(kernelCtxBuilder_ is nullptr!)); tilingCtxBuilder_-Workspace(workspace); }这里使用的是tilingCtxBuilder_gert::OpTilingContextBuilder类型而非 Kernel 侧的kernelCtxBuilder_gert::OpKernelContextBuilder。也就是说workspace 数据只会被写入TilingContext 的内存布局中。如果在BuildKernelRunContext()场景KernelContext / TilingParseContext下调用Workspace()数据写入的内存区域与实际读取的内存布局不一致就会产生未定义行为。因此✅ 正确场景.Workspace(ws)后调用.BuildTilingContext()❌ 错误场景.Workspace(ws)后调用.BuildKernelRunContext() 替代方案在 Kernel 场景下需要向 context 传入数据请使用Outputs()接口。同样的约束也出现在 TilingData 接口文档 中二者是 Tiling Context 构造组中一对成对出现、同生共死的接口。四、源码实现剖析数据是如何流入 TilingContext 的ContextBuilder的完整调用链分为三层对外 API 层context_builder.h 第 112 行 声明ContextBuilder Workspace(gert::ContinuousVector *workspace)实现转发层context_builder_impl.cpp 第 358-362 行 的ContextBuilderImpl::Workspace()将其转发给tilingCtxBuilder_gert 底层构造器层gert::OpTilingContextBuilder::Workspace()将指针写入最终构建的gert::TilingContext内部成员。从 context_builder_impl.cpp 构造函数 可以看到ContextBuilderImpl在创建时同时初始化了两个底层构造器kernelCtxBuilder_ std::make_uniquegert::OpKernelContextBuilder(); tilingCtxBuilder_ std::make_uniquegert::OpTilingContextBuilder();其中 Tiling 构造器还会预填默认值OpName(default_name)、OpType(default_type)、IONum(1, 1)等这些默认值可通过SetOpNameType()、NodeIoNum()等接口覆盖。最终BuildTilingContext()的执行路径context_builder_impl.cpp 第 104-137 行依次完成校验错误标志 → 组装输入/输出张量 →tilingCtxBuilder_-Build()生成gert::ContextHoldergert::TilingContext→ 将其 reinterpret_cast 为KernelRunContext并封装进KernelRunContextHolder返回。整个过程可见Workspace()注入的数据与最终GetContextgert::TilingContext()拿到的对象是同一套内存布局这正是Workspace 必须服务于 BuildTilingContext的底层原因。五、完整调用示例可复制、可运行的实战代码结合 官方调用示例 与仓库测试代码给出一个完整的 workspace 注入流程5.1 官方文档示例原型void AddWorkspaceData(gert::ContinuousVector *ws) { ...... auto builder context_ascendc::ContextBuilder() .Workspace(ws) .BuildTilingContext(); ...... }5.2 仓库测试中的完整范式在 test_tiling.cpp 的 TestTilingContextBuildWithConstValue 用例 中Workspace()与其他 Tiling 接口组合使用形成了标准链路// 1. 创建 workspace 尺寸容器申请 4096 个 size_t 元素的能力空间 auto workspace_size_holder gert::ContinuousVector::Createsize_t(4096); auto ws_size reinterpret_castgert::ContinuousVector*(workspace_size_holder.get()); // 2. 构造 TilingData容量 4096 字节 auto param gert::TilingData::CreateCap(4096); // 3. 链式构造 TilingContext auto holder context_ascendc::ContextBuilder() .NodeIoNum(6, 1) // 6 个输入1 个输出 .IrInstanceNum({1, 1, 1, 1, 1, 1}) // 每个输入 1 个 IR 实例 .AddInputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND, x_shape, reinterpret_castvoid*(x_const_value.data())) // 常量输入 .AddInputTd(1, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND, weight1_shape) .AddOutputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND, output_shape) .AddAttr(activation, active_type) .AddAttr(inner_precise, static_castint64_t(1)) .TilingData(param.get()) // 注入 TilingData .Workspace(ws_size) // 注入 workspace 指针 .AddPlatformInfo(Ascend910B) // 指定 SoC 版本 .BuildTilingContext(); // 最终构建 // 4. 校验构建成功并取出 TilingContext 供 Tiling 函数使用 EXPECT_NE(holder, nullptr); gert::TilingContext* tilingContext holder-GetContextgert::TilingContext();该用例随后通过GetInputShape()、GetOutputShape()、GetInputDesc()、GetOutputDesc()对构造结果做断言校验验证了 TilingContext 中 shape、dtype 等信息的正确性是使用Workspace()后如何验证 Tiling 函数的直接参考。5.3 异常场景的防御性写法测试中还覆盖了Workspace()配合异常输入的返回行为TestAddInputTdMallocFailed当张量尺寸计算异常此处通过 mock 使尺寸超大导致内存分配失败时BuildTilingContext()返回nullptrTestTilingContextIoFailed当输入张量描述不合法shape 含 -1 等非法维度时同样返回nullptr。因此生产代码中应始终检查返回值auto holder context_ascendc::ContextBuilder() .Workspace(ws_size) .BuildTilingContext(); if (holder nullptr) { // 处理构造失败检查输入/输出描述、TilingData 容量等是否合法 return; } gert::TilingContext* tilingContext holder-GetContextgert::TilingContext();六、Workspace 在真实算子工程中的角色Workspace()注入的 workspace 信息在真实算子工程中有明确的落点。在 matmul 高级 API 示例 中可以看到Host 侧通过ascendcPlatform-GetLibApiWorkSpaceSize()获取系统 workspace 大小与用户 workspace 大小求和后经aclrtMalloc申请设备内存最终作为 Kernel 参数传入size_t userWorkspaceSize 0; size_t systemWorkspaceSize static_castsize_t(ascendcPlatform-GetLibApiWorkSpaceSize()); size_t workspaceSize userWorkspaceSize systemWorkspaceSize; uint8_t* workspaceDevice; aclrtMalloc((void**)workspaceDevice, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); matmul_customnumBlocks, 0, stream(aDevice, bDevice, cDevice, workspaceDevice, tiling);在 Tiling 下沉场景的 Host 侧代码 中Tiling 函数通过context-GetWorkspaceSizes(1)写出运行时 workspace 大小并设置为系统 workspace 空间 用户 workspace 空间。由此可以理解ContextBuilder::Workspace()模拟的正是 Tiling 阶段确定 workspace 需求、Kernel 阶段按需使用这一段工作内存的完整链路是 Host 侧 Tiling 单测中不可或缺的一环。七、小结与使用建议要点结论用途向 TilingContext 注入gert::ContinuousVector*类型的 workspace 指针返回ContextBuilder支持链式调用前置约束必须以BuildTilingContext()结尾使用Kernel 场景改用Outputs()创建方式gert::ContinuousVector::Createsize_t(capacity)后 reinterpret_cast失败处理BuildTilingContext()返回nullptr时检查输入/输出描述合法性源码依据context_builder.h、context_builder_impl.cpp测试依据test_tiling.cppWorkspace()虽然只是ContextBuilder众多链式方法之一但它与TilingData()、AddPlatformInfo()共同构成了 TilingContext 的完整信息注入面。掌握它的约束边界只服务于BuildTilingContext()与配套写法Create → reinterpret_cast → 链式注入 → 判空 → GetContext即可在 asc-devkit 中稳定地构建 Tiling 单测环境快速定位 Tiling 函数的切分逻辑问题。更多接口如AddInputTd、AddAttr、BuildTilingContext可继续查阅 ContextBuilder 文档目录。赞分享人工智能深度学习算子库CANNAscend【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址https://gitcode.com/cann/asc-devkit点击查看免费下载相关推荐asc-devkit Tiling 调优指南ContextBuilder::AddAttr 接口详解与 TilingContext 属性构造实战asc devkit Tiling 调优指南ContextBuilder::AddAttr 接口详解与 TilingContext 属性构造实战 在 asc人工智能深度学习算子库CANNAscendasc-devkit 算子开发Conv3D Tiling 的 SetStride 接口用法与原理详解asc devkit 算子开发Conv3D Tiling 的 SetStride 接口用法与原理详解 导读 本文聚焦 CANN asc devkit 开源算子人工智能深度学习算子库CANNAscendasc-devkit Tiling 调测指南ContextBuilder::PlatformInfo 接口详解与底层实现剖析asc devkit Tiling 调测指南ContextBuilder::PlatformInfo 接口详解与底层实现剖析 本文聚焦 asc devkit人工智能深度学习算子库CANNAscend上一篇WechatDecrypt让微信数据解密更安全简单的本地工具下一篇LeetCode 3. 无重复字符的最长子串详解InterviewGuide 哈希表刷题笔记中的滑动窗口三版演进创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考